我正在使用一个第三方专有DLL,但我无法获取其源代码。然而,使用SWIG 1.3.39生成的包装器代码对我来说是可用的。这个包装器代码由一个C++文件组成,它使用一些描述DLL的头文件编译为DLL,以及一个C#项目,该项目通过PInvoke调用C++包装器DLL。
根据供应商文档的解释,我将解决方案中的所有内容都编译为x86或x64,具体取决于目标平台。供应商提供专有DLL的32位和64位版本,我已确保在给定的构建中使用正确的版本。我的机器是32位的。在我的机器上测试x86版本的应用程序,无论是发布版还是调试版,似乎都可以正常工作。然而,在64位上,应用程序在调试模式下可以工作,但在发布模式下会出现System.AccessViolationException错误。
我阅读了这篇不错的博客文章,它似乎很好地描述了调试与发布的问题,以及这个问题和答案引起了博客文章。然而,我不确定如何在这种情况下解决问题。
AccessViolationException似乎在尝试返回任何实际长度的字符串(或尝试返回)时第一次发生在C++包装器中。以下是有问题的C#代码:
我已经尝试过使用
根据供应商文档的解释,我将解决方案中的所有内容都编译为x86或x64,具体取决于目标平台。供应商提供专有DLL的32位和64位版本,我已确保在给定的构建中使用正确的版本。我的机器是32位的。在我的机器上测试x86版本的应用程序,无论是发布版还是调试版,似乎都可以正常工作。然而,在64位上,应用程序在调试模式下可以工作,但在发布模式下会出现System.AccessViolationException错误。
我阅读了这篇不错的博客文章,它似乎很好地描述了调试与发布的问题,以及这个问题和答案引起了博客文章。然而,我不确定如何在这种情况下解决问题。
AccessViolationException似乎在尝试返回任何实际长度的字符串(或尝试返回)时第一次发生在C++包装器中。以下是有问题的C#代码:
// In one file of the C# wrapper:
public string GetKey()
{
// swigCPtr is a HandleRef to an object already created
string ret = csWrapperPINVOKE.mdMUHybrid_GetKey(swigCPtr);
return ret;
}
// In the csWrapperPINVOKE class in another file in the C# wrapper:
[DllImport("csWrapper.dll", EntryPoint="CSharp_mdMUHybrid_GetKey")]
public static extern StringBuilder mdMUHybrid_GetKey(HandleRef jarg1);
以下是来自 C++ 封装器的麻烦的 C++ 代码:
SWIGEXPORT char * SWIGSTDCALL CSharp_mdMUHybrid_GetKey(void * jarg1) {
char * jresult ;
mdMUHybrid *arg1 = (mdMUHybrid *) 0 ;
char *result = 0 ;
arg1 = (mdMUHybrid *)jarg1;
result = (char *)(arg1)->GetKey();
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT
已经被定义为__declspec(dllexport)
。在调试中,我发现SWIG_csharp_string_callback
被定义为:
/* Callback for returning strings to C# without leaking memory */
typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *);
static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL;
被设置为委托(在C#封装器中):
static string CreateString(string cString) {
return cString;
}
我已经尝试过使用
Marshal.PtrToStringAut
等结构来修改此代码,但无济于事。我该如何排除和/或解决这个问题?