Как вызвать эту функцию C ++? - PullRequest
0 голосов
/ 06 февраля 2012

У меня есть следующая функция:

bool __declspec(dllexport) COMS_HL7QueryAnswer(char *szZone,char* szMessage, char** o_szAnswer)

И я вызываю его из C # так:

public static extern bool COMS_HL7QueryAnswer(string szZone,string szMessage, out StringBuilder szAnswer);

Это работает в Windows 2003, но я получаю исключения нарушения прав доступа в W2008 и похоже, что они происходят на границе PInvoke. Любая помощь будет отличной.

Спасибо.

РЕДАКТИРОВАТЬ: Похоже, AccessViolationException происходит на границе PInvoke, потому что:

  1. У меня нет стека вызовов, кроме функции C #.
  2. Когда я иду с отладчиком, я могу F10 до последней функции C ++, и когда я выхожу из}, тогда я иду к обработчику исключений C #.

Ответы [ 2 ]

3 голосов
/ 06 февраля 2012

Вам нужно будет использовать

[DllImport(CallingConvention = CallingConvention.Cdecl)]
public static extern bool COMS_HL7QueryAnswer(string szZone,string szMessage, out IntPtr szAnswer);

Поскольку p / invoke не знает, как правильно освободить *o_szAnswer, вам необходимо сохранить указатель и передать его правильной функции освобождения,после извлечения данных.

Если вам разрешено изменять сторону C ++, вы можете сделать несколько вещей, чтобы сделать это более удобным для p / invoke.Или вы можете использовать слой C ++ / CLI.

1 голос
/ 06 февраля 2012

Ваш код пропускает память.Да, W2003 будет молча игнорировать попытку маршалла pinvoke освободить строку.W2008 имеет гораздо более строгий менеджер памяти и не смирится с ним, он вызывает AccessViolation.Вы можете сохранить утечку памяти с помощью IntPtr и Marshal.PtrToStringAnsi ().Если вы можете исправить код на C, то выделение буфера строк с помощью CoTaskMemAlloc () решит проблему, маршаллер pinvoke использует CoTaskMemFree ().

Реальное исправление - char * вместо char **, так что вызывающая сторонаможет передать буфер для заполнения строкой.StringBuilder без out из C #.С дополнительным аргументом, который дает Capacity, чтобы вы не повредили кучу мусора случайно, когда строка не подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...