Создание DLL, вызываемой из C#C#

Место общения программистов C#
Ответить
Anonymous
 Создание DLL, вызываемой из C#

Сообщение Anonymous »

Я работаю в сфере грузоперевозок, где мы используем интерфейс J1939 под названием RP1210. Этот стандарт определяет, как должны создаваться 32-битные библиотеки DLL для общего интерфейса с аппаратными устройствами J1939 (CAN Bus).
Я создал программу на C#, которая использует
NativeMethods.LoadLibrary()
NativeMethods.GetProcAddress
Marshal.GetDelegateForFunctionPointer
для создания функций C# для функций библиотеки dll. Эта программа работает нормально.
Однако мне нужно создать свою собственную DLL, и у меня возникли проблемы, с которыми я надеялся, что кто-нибудь сможет помочь. Я использую Visual Studio 2019.
В качестве примера в документации RP120 указано, что функция должна быть объявлена ​​следующим образом:

Код: Выделить всё

void DLLEXPORT WINAPI RP1210_ReadVersion(char* DLLMajor, char* DLLMinor, char* APIMajor, char* APIMinor)
В C# я использую этот код для получения адреса ReadVersion из DLL

Код: Выделить всё

pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "RP1210_ReadVersion");
if (pAddressOfFunctionToCall != IntPtr.Zero)
{
RP1210_ReadVersion = (TRP1210_READVERSION)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(TRP1210_READVERSION));
}
TRP1210_READVERSION определяется как

Код: Выделить всё

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate short TRP1210_READVERSION(StringBuilder DLLMajor, StringBuilder DLLMinor, StringBuilder APIMajor, StringBuilder APIMinor);
Это все работает для DLL, созданных другими компаниями.
При создании своей собственной DLL я использую такое объяснение

Код: Выделить всё

extern __declspec(dllexport) short _cdecl RP1210_ReadVersion(char* DLLMajor, char* DLLMinor, char* APIMajor, char* APIMinor)
В этом случае GetProcAddress находит адрес, а GetDelegateForFunctionPointer возвращает указатель.
Но если я попытаюсь вызвать функцию, я получу исключение несбалансированного стека
если я использую точное определение, как в документации, и использую WINAPI

Код: Выделить всё

extern __declspec(dllexport) short WINAPI RP1210_ReadVersion(char* DLLMajor, char* DLLMinor, char* APIMajor, char* APIMinor)
тогда вызов GetProcAddress завершится неудачей
если я перейду на __stdcall, как в моем определении типа C#

Код: Выделить всё

extern __declspec(dllexport) short __stdcall RP1210_ReadVersion(char* DLLMajor, char* DLLMinor, char* APIMajor, char* APIMinor)
вызов GetProcAddress также завершается с ошибкой
Я не понимаю, что мне нужно сделать, чтобы определить функцию и чтобы вызов GetProcAddress был успешным, а функция работала без повреждения стека.

Подробнее здесь: https://stackoverflow.com/questions/798 ... om-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»