c# - 在 C# 项目中导入 C++ dll

标签 c# c++ winapi pinvoke dllimport

我有一个用于监视打印机的 C++ dll(使用 FindFirstPrinterChangeNotification)。我正在为它制作 C# Wrapper:

private static class NativeMethods {
        [DllImport("kernel32", SetLastError = true)]
        public static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32", SetLastError = true)]
        public static extern bool FreeLibrary(IntPtr hModule);
}

    public string LibPath;
    private IntPtr LibPtr;
    private GBtMX GBtMain;

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate void GBtMX();

    public GhostBuster() {
        LibPath = AppDomain.CurrentDomain.BaseDirectory + @"\GhostBusterC.dll";
    }

    public string Init() {
        if (!File.Exists(LibPath))
            return "Incorrect path " + LibPath;
        LibPtr = NativeMethods.LoadLibrary(LibPath);
        if (LibPtr == IntPtr.Zero)
            return "Couldn't import library. Error(GetLastWin32Error): " + Marshal.GetLastWin32Error().ToString();

        IntPtr GBtMainPtr = NativeMethods.GetProcAddress(LibPtr, "tmain");
        if (GBtMainPtr == IntPtr.Zero)
            return "No access to GhostBuster.tmain.  Error (GetLastWin32Error): " + Marshal.GetLastWin32Error().ToString();
        GBtMain = (GBtMX)Marshal.GetDelegateForFunctionPointer(GBtMainPtr, typeof(GBtMX));            
        return "";

它返回“无法访问 GhostBuster.tmain。错误 (GetLastWin32Error):0”。 我究竟做错了什么? 提前致谢。

最佳答案

您没有在 p/invoke 中指定 SetLastError,这就是 Marshal.GetLastWin32Error() 无法返回任何有用信息的原因。 p/调用应该是

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetProcAddress(
    IntPtr hModule, 
    [MarshalAs(UnmanagedType.LPStr)]
    string lpProcName
);

另请注意,明确说明过程名称的编码是有意义的。这始终是一个 ANSI 字符串,反射(reflect)了 PE 格式。

当您进行此更改时,我预计错误将是 ERROR_PROC_NOT_FOUND,表明 DLL 不会使用您传递给 GetProcAddress 的名称导出任何内容。

检查您是否正确拼写了函数名称。你的字母大小写正确吗?构建 DLL 时是否应用了任何修饰或重整?使用 dumpbin 或 Dependency Walker 等工具检查 DLL 导出的名称。

关于c# - 在 C# 项目中导入 C++ dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45836164/

相关文章:

c# - 包含数字和字母的orderby()

c# - 字符串、对象和整数之间的转换和解析

c# - 如何以编程方式连接到 VPN?

c++ - 结构崩溃

c++ - 在新线程中调用代码

c# - 使用 p/invoke 和 win-api 监控音频线路输入 (C#)

c++ - 如何比较两个 HANDLE 类型的变量

c# - C# 类中的绑定(bind)(映射)Json

c++ - 需要在 C++ 中创建一个单词匹配器

c++ - 窗口只会在鼠标移动时更新