Вызов C++ DLL только с экспортом __declspec из C# ⇐ C++
Вызов C++ DLL только с экспортом __declspec из C#
Я отправляю новый вопрос по обсуждаемой теме, так как не могу найти решение или тот же сценарий, что и я.
Я создаю решение .NET 8 и пытаюсь вызвать функции C++ из .DLL.
Эта DLL не моя, у меня нет для нее ни файлов .lib, .obj, ни .pdb.
Рассматриваемая DLL — это более старая сборка RakNet, поэтому я могу использовать последний доступный код в GitHub в качестве ссылки, однако эта DLL имеет более старую версию, поэтому я не могу просто собрать ее заново из GitHub.
Основная причина использования именно этой .DLL заключается в том, что я разрабатываю «совместимый» собственный сервер для игры, поэтому клиент также будет использовать эту старую версию RakNet.
С помощью декомпиляции с помощью Cutter или Ghidra я проверил, что экспортированные функции остались такими же, как в коде GitHub.
Эти функции экспортируются в обычном формате __declspec, а не как «extern «C»», и из-за этого C#, похоже, не может загрузить их и найти функции при использовании аннотации [DLLImport()].
Я пытался создать файл .lib с помощью VS Tools, но это не сработало.
Потратив на это более 5 часов, я решил обратиться за помощью и проверить, сталкивался ли кто-нибудь с подобной ситуацией и знает, возможно ли это и как вызвать C++ DLL из C# с этими ограничениями. Очень жду советов и идей.
Спасибо.
РЕДАКТИРОВАТЬ 1:
Добавление более конкретного контекста текущей проблемы и ошибки.
Чтобы определить расположение DLL и быть более точным, я загружаю ее с помощью:
[DllImport("kernel32.dll", SetLastError = true)] частный статический extern IntPtr LoadLibrary (строка dllToLoad); общественная статическая пустота LoadRakNetDll() { вар-дескриптор = LoadLibrary (dllPath); если (дескриптор == IntPtr.Zero) { Console.WriteLine("Не удалось загрузить DLL"); } } Затем рассматриваемый метод, с которым я пытаюсь взаимодействовать, объявляется следующим образом:
[DllImport("RakNet64", CallingConvention = CallingConvention.StdCall)] public static extern int Startup(uint maxConnections, SocketDescriptorocketDescriptors, uintsocketDescriptorCount, int threadPriority); Я проверил определение EntryPoint, однако из исключения я увидел, что если его опустить, .NET будет использовать имя метода в качестве точки входа.
Исключение, которое я получаю:
System.EntryPointNotFoundException HResult=0x80131523 Сообщение=Невозможно найти точку входа с именем «Запуск» в DLL «RakNet64». Я также тестировал изменение CallingConvention, но безрезультатно.
Проведение исследований, опрос ИИ и т. д. повсюду указывает на необходимость использования функций экспорта DLL с использованием "extern "C", но я могу ошибаться.
Я отправляю новый вопрос по обсуждаемой теме, так как не могу найти решение или тот же сценарий, что и я.
Я создаю решение .NET 8 и пытаюсь вызвать функции C++ из .DLL.
Эта DLL не моя, у меня нет для нее ни файлов .lib, .obj, ни .pdb.
Рассматриваемая DLL — это более старая сборка RakNet, поэтому я могу использовать последний доступный код в GitHub в качестве ссылки, однако эта DLL имеет более старую версию, поэтому я не могу просто собрать ее заново из GitHub.
Основная причина использования именно этой .DLL заключается в том, что я разрабатываю «совместимый» собственный сервер для игры, поэтому клиент также будет использовать эту старую версию RakNet.
С помощью декомпиляции с помощью Cutter или Ghidra я проверил, что экспортированные функции остались такими же, как в коде GitHub.
Эти функции экспортируются в обычном формате __declspec, а не как «extern «C»», и из-за этого C#, похоже, не может загрузить их и найти функции при использовании аннотации [DLLImport()].
Я пытался создать файл .lib с помощью VS Tools, но это не сработало.
Потратив на это более 5 часов, я решил обратиться за помощью и проверить, сталкивался ли кто-нибудь с подобной ситуацией и знает, возможно ли это и как вызвать C++ DLL из C# с этими ограничениями. Очень жду советов и идей.
Спасибо.
РЕДАКТИРОВАТЬ 1:
Добавление более конкретного контекста текущей проблемы и ошибки.
Чтобы определить расположение DLL и быть более точным, я загружаю ее с помощью:
[DllImport("kernel32.dll", SetLastError = true)] частный статический extern IntPtr LoadLibrary (строка dllToLoad); общественная статическая пустота LoadRakNetDll() { вар-дескриптор = LoadLibrary (dllPath); если (дескриптор == IntPtr.Zero) { Console.WriteLine("Не удалось загрузить DLL"); } } Затем рассматриваемый метод, с которым я пытаюсь взаимодействовать, объявляется следующим образом:
[DllImport("RakNet64", CallingConvention = CallingConvention.StdCall)] public static extern int Startup(uint maxConnections, SocketDescriptorocketDescriptors, uintsocketDescriptorCount, int threadPriority); Я проверил определение EntryPoint, однако из исключения я увидел, что если его опустить, .NET будет использовать имя метода в качестве точки входа.
Исключение, которое я получаю:
System.EntryPointNotFoundException HResult=0x80131523 Сообщение=Невозможно найти точку входа с именем «Запуск» в DLL «RakNet64». Я также тестировал изменение CallingConvention, но безрезультатно.
Проведение исследований, опрос ИИ и т. д. повсюду указывает на необходимость использования функций экспорта DLL с использованием "extern "C", но я могу ошибаться.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Godot (4.3) Проблема с экспортом в Windows, неожиданное поведение сценария C#
Anonymous » » в форуме C# - 0 Ответы
- 28 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Конвертировать datagridview в файл PDF... как настроить столбцы перед экспортом PDF?
Anonymous » » в форуме C# - 0 Ответы
- 17 Просмотры
-
Последнее сообщение Anonymous
-