Создать DLL из .lib файла - PullRequest
       32

Создать DLL из .lib файла

0 голосов
/ 02 октября 2018

Этот вопрос основан на следующем сообщении: https://stackoverflow.com/users/9999861/blackbriar

Теперь у меня есть проблема, что каждый раз, когда я хочу использовать DLL, System.EntryPointNotFoundException происходит.В сообщении об исключении говорится, что точка входа с именем функции, которую я пытался вызвать, не найдена в моей dll.

Вот пример функции, которая находится в файле .h:

#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int __stdcall LDL_Init(char* code)
...
#ifdef __cplusplus
}
#endif

И я импортировал функцию в C # следующим образом:

[DllImport("C:\\Path\\To\\Dll\\Example.dll", EntryPoint="LDL_Init", CallingConvention=CallingConvention.StdCall)]

public static extern int LDL_Init( [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder code );

Кто-то понимает, что я делаю неправильно?

Далее Попробуйте:

Я проанализировал сгенерированную dll с помощью Dependency Walker и обнаружил, что ни одна функция не была экспортирована.Итак, я написал обертку-класс.Вот новые примеры кода:

В Library.h:

int LDL_Init(char* code);

В LibraryWrapper.h:

#pragma once

    class __declspec(dllexport) LibraryWrapper
    {
    public:
        static int __cdecl LDL_Init(char* code);
    };

В LibraryWrapper.cpp.

#include "Library.h"
#include "LibraryWrapper.h"

int LibraryWrapper::LDL_Init(char* code){
    return LDL_Init(code);
}

В Library.cs:

[DllImport("C:\\Path\\To\\Dll\\Example.dll")]
public static extern int LDL_Init( [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder code );

К сожалению, у меня при выполнении программы такой же результат: Старый добрый System.EntryPointNotFoundException ...

Вот скриншотрезультат Dependency Walker: Screenshot of Dependency walker

и без подкрашивания методов C ++: Dependency walker screenshot without undecorating

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Если возможно, используйте __cdecl.

__ stdcall добавит @parameter_bytes после имени функции.

0 голосов
/ 02 октября 2018

Я "решил" проблему с помощью следующей настройки в файле Library.cs:

[DllImport("C:\\Path\\To\\Dll\\Example.dll", EntryPoint="?LDL_Init@LibraryWrapper@@SAHPEAD@Z")]
public static extern int LDL_Init( [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder code );

Строка EntryPoint основана на имени функции, которое Dependency Walker извлек из моей библиотеки DLL.После этого у меня возникла проблема, заключающаяся в том, что выполнение кода остановилось на строке

return LDL_init(code);

в файле LibraryWrapper.cpp.Обнаружил это, включив «отладку собственного кода» и нажав паузу во время отладки.

Тем временем я обнаружил .dll, предоставленную производителем устройства, которым я хочу управлять.Я проанализировал .dll с помощью Dependency Walker и вставил EntryPoints.Теперь это работает.Спасибо за поддержку.

0 голосов
/ 02 октября 2018

Вы можете использовать инструмент Microsoft DUMPBIN.EXE для проверки экспорта:

> dumpbin /EXPORTS Example.dll
Microsoft (R) COFF/PE Dumper Version 14.14.26433.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file Example.dll

File Type: DLL

  Section contains the following exports for Example.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          2    0 000110C3 LDL_Init = @ILT+190(LDL_Init)
          1    1 00011087 foo = @ILT+130(foo)

  Summary

        1000 .00cfg
        1000 .data
        1000 .idata
        2000 .pdata
        3000 .rdata
        1000 .reloc
        1000 .rsrc
        8000 .text
       10000 .textbss

Любые специальные вещи для компоновщика, такие как __declspec(dllexport) или #pragma comment(lib, ...), должны бытьувиденный компилятором или иным образом, он не будет иметь никакого представления о них, как и компоновщик.Для измененных заголовочных файлов это будет означать включение их как минимум один раз.

В качестве альтернативы для файла определения модуля (.def) потребуется добавить в проект (или добавить аргумент командной строки /DEF filename вручную).

...