Пытался вызвать неуправляемую DLL, но она всегда возвращает нежелательные значения.Пожалуйста помоги! - PullRequest
0 голосов
/ 24 марта 2011

Может кто-нибудь помочь мне разобраться, что не так с приведенным ниже фрагментом кода.Я пытался вызвать старую DLL и провел около 3 дней, но не смог найти, почему мой возвращаемый массив и строка всегда являются ненужными.

Неуправляемые коды:


typedef struct
{
    double a;
    double b;
}UnmanagedStruct, far *lpUnmagedStruct;

//.h file:
__declspec( dllexport ) double far pascal Process(lpUnmagedStruct lpStruct, int size, char far szMessage[]);

//.cpp
extern double far pascal Process(lpUnmagedStruct lpStruct, int size, char far szMessage[])
{
    //Please pay attention here. It's being seen as a pointer to an array
    lpStruct[0] = ...
    lpStruct[2] = ...
    _fstrcpy (szMsg, "Welcome");
}

А вот мои коды в .NET:


[StructLayout(LayoutKind.Sequential)]
public struct ManagedStruct 
{
    public double a;
    public double b;
}

[DllImport("MyDll.dll", EntryPoint="Process", CharSet = CharSet.Ansi)]
public static extern double Process([In, Out]ManagedStruct[] myStruct, int size, string message);

//Implementation
ManagedStruct[] arrayOfStruct = new ManagedStruct[3];
string message;

//Assign values to arrayOfStruct

//Call interop
Process(arrayOfStruct, 3, message);

1 Ответ

1 голос
/ 25 марта 2011

Соглашение о вызовах паскаль - это ваша проблема.Он древний, маршаллер пинвока не поддерживает его.Он передает аргументы слева направо, маршаллер pinvoke принимает stdcall, поэтому передает их справа налево.Вместо этого используйте __stdcall:

__declspec( dllexport ) 
double __stdcall Process(lpUnmagedStruct lpStruct, int size, char* szMessage, int messageSize);

Следующая проблема - строка, для возврата которой необходимо использовать StringBuilder в объявлении и передать инициализированный в вызове:

[DllImport("MyDll.dll", EntryPoint="Process", CharSet = CharSet.Ansi)]
public static extern double Process(ManagedStruct[] myStruct, int size, StringBuilder message, int messageSize);

...
var buffer = new StringBuilder(666);
double retval = Process(arrayOfStruct, 3, buffer, buffer.Capacity);
var message = buffer.ToString();

Я взялсвобода добавления аргумента messageSize, необходимая для безопасного копирования строки в буфер сообщений, не рискуя уничтожить кучу мусора.

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