Как предотвратить AccessViolationException при возврате строки из C ++ в C # в 64-битной Windows?

Я использую стороннюю проприетарную 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 безрезультатно. Как мне найти и / или исправить эту проблему?

9
задан Community 23 May 2017 в 01:53
поделиться