在 c++/cli 中调用本机函数指针
我在托管(c++/cli)混合模式库中有一个本机函数,它调用单独的本机 dll。
这是使用 windows GetProcAdress 初始化一些函数指针的本机函数:
//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 的目录中,则应用程序会在第一次调用后崩溃。 (“访问冲突异常”)
I have a native function inside a managed (c++/cli) mixed-mode library that calls a seperate native dll.
Here is the native function that initializes some function pointers using windows GetProcAdress:
//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);
}
now I want to write a wrapper function that will call this function pointer, but in doing so I get an "AccessViolationException"
public ref struct Wrapper sealed abstract
{
void ManagedFunc(IntPtr hwnd)
{
if (BeginDll())
{
MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));
MYDLL_Func2();
}
}
}
I am not assuming I can call a function pointer in c++/cli code, I am simply wondering a correct way to do this. If I add the api dll's header file and call the functions implicitly, I run into the problem that if the native helper dll is not in the directory with the managed dll the application bombs after the first call. ("AccessViolationException")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
应该是
演员都是邪恶的。将成员函数转换为数据指针是错误的。
should be
Casts are evil. Casting a member function to a data pointer is just wrong.
由于某种原因,汉斯帕萨特发布了正确的答案,但它不再可用,如果有人想知道这是如何解决的,我会总结一下:
函数指针的静态声明导致每个源文件都有其 < em>自己的副本,因此它们在声明文件中变成以下内容
,在源文件中,
他还说将调用约定更改为 _stdcall,但这是在 .C 文件中,但 _cdecl 编译得很好。
然而,我最终还是切换回包含 DLL 的头文件并隐式调用函数。由于某种原因,使用此解决方案时,在调试器外部运行时,我的 C# 客户端出现缓冲区溢出问题。由于在尝试调试时问题并不存在,因此我恢复了不同的解决方案。我想我只需要小心不要将 DLL 包含在我的托管 DLL 和客户端中。
For some reason the correct answer was posted by Hans Passat but it is not available anymore, if anyone wants to know how this was fixed I'll sum it up:
the static declarations of the function pointers were causing each source file to have its own copy so they become the following in the declaration file
and in the source file
he also says to change the calling convention to _stdcall, but this is in a .C file but _cdecl compiles just fine.
I did however end up switching back to including the DLL's header file and calling functions implicitly. For some reason with this solution, I was getting a buffer overrun in my C# client when running outside of the debugger. Seeing as the problem did not exsist while trying to debug it, I reverted to a different solution. I suppose I just need to be careful to not include the DLL with my managed DLL and client.