Я использую стороннюю проприетарную DLL, исходный код которой мне недоступен. Однако код оболочки, который, похоже, был автоматически сгенерирован с использованием SWIG 1.3.39, доступен мне. Код оболочки состоит из файла C ++, который компилируется (с использованием некоторых заголовков, описывающих DLL) в DLL, и проекта C #, который выполняет вызовы PInvoke к DLL-оболочке C ++.
Согласно моей интерпретации документации поставщика, у меня есть скомпилировал все в решении как x86 или x64, в зависимости от целевой платформы. Производитель предоставляет как 32-разрядные, так и 64-разрядные версии проприетарной библиотеки DLL, и я убедился, что использую правильную версию для данной сборки. Моя машина 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
безрезультатно. Как мне найти и / или исправить эту проблему?