C# 在动态加载的DLL库中返回字符串失败

C# 在动态加载的DLL库中返回字符串失败,c#,.net,interop,pinvoke,C#,.net,Interop,Pinvoke,我将完整地向您描述我的问题和过程。我正在为别人的游戏制作一个编辑器,我有一个用C语言编写的包装器DLL,我正在与之通信 起初,我有一个方法列表,使用DllImport从DLL调用函数。第一种方法是CSharp\u new\u ceditor接口,它返回一个IntPtr。然后CSharp\u ceditor interface\u CreateApp将ulong句柄设置为窗口控件,在该控件中绘制图形。最后,我应该调用CSharp\u CEditorInterface\u CloseApp和CSha

我将完整地向您描述我的问题和过程。我正在为别人的游戏制作一个编辑器,我有一个用C语言编写的包装器DLL,我正在与之通信

起初,我有一个方法列表,使用
DllImport
从DLL调用函数。第一种方法是
CSharp\u new\u ceditor接口
,它返回一个
IntPtr
。然后
CSharp\u ceditor interface\u CreateApp
ulong
句柄设置为窗口控件,在该控件中绘制图形。最后,我应该调用
CSharp\u CEditorInterface\u CloseApp
CSharp\u delete\u CEditorInterface
。这些方法使用
HandleRef
,指针从
CSharp\u new\u ceditor接口返回

但是,我需要多次调用creating和deleting方法,第二次调用
CSharp\u CEditorInterface\u CreateApp
时,它抛出了
System.AccessViolationException
。所以我决定使用LoadLibrary和FreeLibrary动态加载和卸载DLL。我编写了一个应用程序,它通过反射浏览所有p/invoke方法,并生成由委托、只读字段和getproces地址组成的代码。然而,正如我发现的,入口点只是部分
CSharp\u new\u ceditor接口
was
\u CSharp\u new_CEditorInterface@0
。使用我的DLL导出查看器,我保存了所有完整的函数名,然后在其中搜索。在构造函数中,我调用
LoadLibrary
并加载相应的函数。在
Dispose
中,有
freebrary

这个解决方案工作得很好,函数被称为OK,直到我发现一些返回字符串的函数抛出了
AccessViolationException
。使用
DllImport
方法时,它们工作正常。我还发现,当从静态类调用任何函数,从而加载另一个模块时,调用有问题的函数现在是可以的,它们返回适当的值。但是,在动态卸载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并不是为了一次加载多个而创建的


有人能帮帮我吗?

试试这个我希望这个能帮到你

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);

//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
     int errorCode = Marshal.GetLastWin32Error();
     throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}

//Free
if(Handle != IntPtr.Zero)
        FreeLibrary(Handle);
如果要首先调用函数,则必须创建与此函数匹配的delegate 然后使用WinApi GetProcAddress

[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); 


IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);

您能否展示一些您实际使用的真实代码,并指出您在代码中遇到问题的地方,这有点难/很难理解显示代码通常比sudo编码更容易为其他人提供帮助。。另外,看看Singleton和/或如何为运行Code的单个实例创建互斥,我想我已经描述了所需的一切。返回字符串的非托管方法在通过DllImport调用时工作正常,但在通过GetProcAddress的指针调用时失败。当使用DllImport加载指定的DLL时,该方法工作正常,直到卸载和重新加载。感谢您的努力,但我已经为函数提供了所有必要的委托。我还检查了句柄不是零。我敢肯定。其他函数以同样的方式加载。只是那些返回字符串的。也许马歇尔斯能解决这个问题?