代码之家  ›  专栏  ›  技术社区  ›  Tom Fobear

在C++/CLI中调用本机函数指针

  •  1
  • Tom Fobear  · 技术社区  · 16 年前

    在托管(C++/CLI)混合模式库中,我有一个本机函数,它调用一个分离的本地DLL。

    以下是使用Windows GetProcAddress初始化某些函数指针的本机函数:

    //in header
    static HMODULE hDll;
    static void (*MYDLL_Func1)(void*);
    static void (*MYDLL_Func2)(void);
    
    int BeginDll()
    {
        if (!hDll) {
            hDll= LoadLibraryHelper("mydll.dll");
            if (hDll) {
                MYDLL_Func1 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func1");
                MYDLL_Func2 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func2");
    
                if (!MYDLL_Func1||
                    !MYDLL_Func2)
                {
                    FreeLibrary(hDll); hDll= NULL;
                } else {
                    Log("were good to go");
                }
            }
        }
        return (hDll!= NULL);
    }
    

    现在,我想编写一个包装函数来调用这个函数指针,但这样做时,我得到一个“accessViolationException”

    public ref struct Wrapper sealed abstract
    {
        void ManagedFunc(IntPtr hwnd)
        {
            if (BeginDll())
            {
                MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));
                MYDLL_Func2();
            }
        }
    }
    

    我不认为我可以调用函数指针在C++/CLI代码,我只是想知道一个正确的方法来做到这一点。如果添加api dll的头文件并隐式调用函数,我会遇到这样的问题:如果本机助手dll不在托管dll的目录中,则应用程序在第一次调用后会爆炸。(accessViolationException)

    2 回复  |  直到 12 年前
        1
  •  1
  •   Ben Voigt    16 年前
    MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));
    

    应该是

    MYDLL_Func1(hwnd.ToPointer());
    

    施法是邪恶的。将成员函数强制转换为数据指针是错误的。

        2
  •  1
  •   Tom Fobear    16 年前

    出于某种原因,汉斯·帕萨特发布了正确的答案,但该答案已不再可用,如果有人想知道如何解决此问题,我将对其进行总结:

    函数指针的静态声明导致每个源文件 拥有 复制,使其成为声明文件中的以下内容

    extern void (*MYDLL_Func1)(void*);
    

    在源文件中

    void (*MYDLL_Func1)(void*);
    

    他还说要将调用约定更改为\u stdcall,但这是一个.c文件,但\u cdecl编译得很好。

    不过,我还是切换回了包含dll头文件的位置,并隐式调用了函数。由于这个解决方案的某些原因,当在调试程序之外运行时,我的C客户机中出现了缓冲区溢出。由于在尝试调试时问题并不存在,所以我返回到另一个解决方案。我想我只是需要小心不要将DLL包含在我的托管DLL和客户机中。

    推荐文章