我将完整地向您描述我的问题和过程。我正在为其他人的游戏制作编辑器,并且我有一个用 C 语言编写的包装 DLL,我正在与之通信。
起初我有DllImport
从 DLL 调用函数的方法列表。第一种方法是CSharp_new_CEditorInterface
返回一个IntPtr
. 然后CSharp_CEditorInterface_CreateApp
哪个tokeulong
句柄到窗口控制它将在哪里绘制图形。最后我应该调用CSharp_CEditorInterface_CloseApp
and CSharp_delete_CEditorInterface
。这些方法采用HandleRef
从返回的 with 指针CSharp_new_CEditorInterface
。
但是,我需要多次调用创建和删除方法CSharp_CEditorInterface_CreateApp
,第二次调用时,它会抛出System.AccessViolationException
. 所以我决定用 LoadLibrary 和 FreeLibrary 动态加载和卸载 DLL。我编写了一个应用程序,它通过反射浏览所有 p/invoke 方法并生成由委托、只读字段和 GetProcAddress-es 组成的代码。然而,正如我发现的那样,入口点只是部分的。CSharp_new_CEditorInterface
是_CSharp_new_CEditorInterface@0
。使用我的 DLL 导出查看器,我保存了所有完整的函数名称,然后在其中进行了搜索。在构造函数中,我调用LoadLibrary
并加载适当的函数。在Dispose
,有FreeLibrary
。
该解决方案运行良好,函数调用正常,直到我发现一些返回字符串的函数正在抛出AccessViolationException
. 他们在使用DllImport
方法时工作正常。我还发现,当从静态类调用 ANY 函数,从而加载另一个模块时,调用有问题的函数现在可以并且它们返回适当的值。但是,动态卸载DLL并重新加载后,它再次不起作用并猜测抛出了哪个异常。
现在我调用哪个函数以及按什么顺序:
--When initializing--
LoadLibrary(string) (winapi)
--bunch of GetProcAddress, Marshal.GetDelegateForFunctionPointer--
new_CEditorInterface() (from DLL)
CreateApp(HandleRef, ulong) (from DLL)
--When closing in Dispose--
CloseApp(HandleRef) (from DLL)
delete_CEditorInterface(HandleRef) (from DLL)
FreeLibrary(IntPtr) (winapi)
我应该注意,DLL 不是为了一次加载多个而创建的。
有人可以帮我吗?