C # - вызов неуправляемой функции C ++ с передачей LPVARIANT - PullRequest
1 голос
/ 22 июня 2011

Я хочу вызвать следующую функцию из моего управляемого кода:

short LS_LoadConfig(LS_ID SensorID,LPVARIANT varConfigPathFile,BOOL bInit)

Вот как я объявляю функцию extern в моем классе C #:

[DllImport("LineSensor.dll", EntryPoint = "#16")]
private static extern Int16 LS_LoadConfig(
        Int16 deviceId,
        IntPtr variantFilePath,
        int init);

И вот какЯ создаю экземпляр VARIANT и получаю указатель на него.Затем я вызываю функцию C #:

string filepath = @"C:\Windows\ ...";
IntPtr variantFilePath = Marshal.AllocCoTaskMem(200);
Marshal.GetNativeVariantForObject(filepath, variantFilePath);
LS_LoadConfig(device.Id, variantFilePath, initLineSensor);

Проблема заключается в том, что я продолжаю получать сообщения об ошибках, такие как «вызов функции LS_LoadConfig разбалансирует стек, проверьте, что параметры соответствуют неуправляемой подписи».

Похоже, что проблема вызвана вторым аргументом "variableFilePath", так как он неправильно распределен и его размер в неуправляемой куче не соответствует одному из адресов (32-битный в моем случае).Я попытался изменить тип в сигнатуре функции C # с IntPtr на int следующим образом:

[DllImport("LineSensor.dll", EntryPoint = "#16")]
    private static extern Int16 LS_LoadConfig(
        Int16 deviceId,
        int variantFilePath,
        int init);

Я попытался вызвать функцию, передав случайное число, и она стала немного лучше, я только что получил ошибку "нарушение доступа к памяти".Очевидно, что случайное число не было действительным адресом.

Кто-нибудь знает решение этой проблемы?

Спасибо за любую полезную информацию.

Ответы [ 2 ]

1 голос
/ 22 июня 2011

Созданное вами нарушение прав доступа не лучше.Это также предотвращает генерирование предупреждения MDA.Если не считать ошибочных типов аргументов, int16 выглядит довольно странно, наиболее вероятная проблема вызвана CallingConvention.Попробуйте StdCall.

И объявите 2-й аргумент как «объект», его маршалинг по умолчанию - VARIANT.Объявите его с ключевым словом ref, чтобы получить LPVARIANT.

0 голосов
/ 22 июня 2011

"вызов функции LS_LoadConfig разбалансировал стек, проверьте, что параметры соответствуют неуправляемой сигнатуре".

Это обычно означает, что вы используете конфликтующие соглашения о вызовах между вашим собственным и управляемымкод.C # по умолчанию использует stdcall, а c / c ++ использует cdecl.Попробуйте указать CallingConvention = CallingConvention.Cdecl.

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