Преобразование статической библиотеки ссылок в динамическую dll

У меня есть .lib файл с его заголовком (.h). Этот файл имеет несколько функций, которые необходимо использовать в приложении С#.

После googling я обнаружил, что мне нужно создать динамическую DLL из этой статической библиотеки и вызвать эту динамическую DLL из кода С# с помощью interop.

  • Я создал проект win32 и DLL выбранного типа.
  • Включен заголовочный файл и добавлен .lib для дополнительных зависимостей.

    Я могу видеть функции, определенные в статической библиотеке (когда я нажимаю Ctrl + пробел).

Как новичок, я не знаю, как я могу экспортировать функцию, которая находится в .lib со следующей подписью:

void testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)

Я хочу такую ​​же подпись в моей динамической DLL с другим именем.

Что писать в файле заголовка и файле .cpp?

Ответ 1

Если вы можете перекомпилировать свою lib, просто добавьте __declspec(dllexport) в подписи всех функций, которые вы хотите экспортировать.

void __declspec(dllexport) testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)

Если вы не можете этого сделать, вы можете экспортировать их, записав вместо этого файл .def. Используя файлы def, вы можете даже изменить имя функции по мере ее экспорта. http://msdn.microsoft.com/en-us/library/28d6s79h.aspx

---- содержимое mylib.def ----

LIBRARY

EXPORTS
   testfun
   newname=testfun2

Затем, когда вы связываете DLL, включите mylib.def

link /dll /machine:x86 /def:mylib.def  mylib.lib

Edit2:

Обратите внимание, что pinvoke предполагает, что функции, которые вы импортируете, будут иметь _stdcall вызов, если вы не скажете иначе. Таким образом, вам может понадобиться сделать это также в коде С#.

[DllImport("mylib.dll", CallingConvention=CallingConvention.Cdecl)]

Или вы можете изменить свой код на С++ на __stdcall

void __declspec(dllexport) __stdcall testfun( char* inp_buff, ...

Ответ 2

Создайте новый проект Dll с помощью мастера приложений Visual Studio и установите флажок "Экспорт символов" на одном из шагов мастера. Он создает образец Dll, который экспортирует класс, функцию и переменную. Вы можете узнать из этого примера, как это сделать. Как правило, каждая экспортированная функция объявляется как __declspec (dllexport). В клиентском проекте он объявлен как __declspec (dllimport). Код Dll использует константу, которая осквернена как __declspec (dllexport) внутри проекта Dll, и __declspec (dllimport) в любом другом месте.

Ответ 3

Это то, что вы можете сделать

  • Добавьте к вам следующий код .H. переименуйте "MYPROJECT" в название вашего проекта

    #ifdef MYPROJECT_EXPORTS
    #define MYPROJECT_API __declspec(dllexport)
    #else
    #define MYPROJECT_API _declspec(dllimport)
    #endif
    
  • Перейдите в Properties- > С++ → Preprocessor и добавьте defenition - MYPROJECT_EXPORTS

  • Добавьте MYPROJECT_API ко всем функциям, которые вы хотите открыть dll, например:

    MYPROJECT_API void Test();
    
  • Перейти к свойствам проекта Общие → Тип конфигурации изменить его на Dynamic Dll

Вы закончили

Ответ 4

Целевая dll, я пишу, является оберткой для популярной библиотеки lzo. Я создал проект под названием LZO.

Вот как это выглядит в моем реальном приложении.

LZO.h

    #ifdef LZO_EXPORTS
    #define LZO_API __declspec(dllexport)
    #else
    #define LZO_API __declspec(dllimport)
    #endif

    extern "C" LZO_API void Decompress(char* inp_buff, 
unsigned short* inp_len, char* buffer_decomp,unsigned *output_len);

LZO.cpp

      #include "stdafx.h"
        #include "LZO.h"
        #include "lzo1z.h"
        #include "lzoconf.h"
        #include "lz_decomp.c"

        LZO_API void Decompress(char* inp_buff, unsigned short* inp_len, char* 
    buffer_decomp,unsigned *output_len)
        {
          //Calling from static library
          lzo_decomp (inp_buff,inp_len,buffer_decomp,output_len,NULL); 
        }

И завершите мой код С#

//P/Invoke declaration
[DllImport("LZO.dll")]
 private static extern void Decompress(
   byte[] inp_buff,
   int inp_len,
   byte[] buffer_decomp,
   ref int output_len
  );        

//And calling it as below
Decompress(src, src.Length, dst, ref outlen);
// src is byte [] 
// dst is also a byte [] 
// oulen is int

где am я wrog???

Ответ 5

можно создать две версии LIB, кулак - это динамический lib, (исходный файл + заголовок + динамический lib) → для доступа к DLL

или static lib = (dynamic lib + DLL) → (исходный файл + заголовок) → для доступа к DLL.

если у вас есть Dynamic Lib > нет возможности создать DLL (вы ничего не можете получить из ничего), динамическая lib - это просто интерфейс,

но если у вас есть Static Lib, тогда нет необходимости в DLL для доступа к его функциям.

Ответ 6

Взгляните на мой ответ на этот вопрос для возможного решения. Почти положительное это будет работать для вас...

Вкратце: включите параметр "Использовать вкладки зависимостей библиотеки" в настройках компоновщика. Если установлено значение "true", это заставит связывать ВСЕ символы и код, объявленные в каждой LIB, указанной в качестве входных данных для проекта.

Ответ 7

Проблема здесь не в том, как декорирован код, это дополнительный шаг создания статической библиотеки, содержащей все точки входа, и попытки построить DLL из этого.

Если вы идете с подходом __delcspec и сначала создаете статическую библиотеку, а затем попытайтесь установить ссылку на него при построении DLL, вам придется решить проблему с отсечкой кода.

Когда вы связываете, obj srcs используются для поиска всех украшенных экспонатов и зависимостей, разрешаются все остальное. Если у вас нет DLL src, поэтому никаких файлов obj (кроме, возможно, dll main), весь код в lib, который вы хотите экспортировать, будет удален (независимо от атрибутов).

Итак, вам либо нужно:

  • Скажите компоновщику, чтобы он не удалял неиспользуемый код, что, вероятно, даст вам много чего вам не нужно.
  • Используйте файл def, чтобы вручную экспортировать экспорт.
  • Свяжите dll с файлами obj, используемыми для создания lib, а не напрямую для ссылки на lib.
  • Или, может быть, создать фиктивный код, который ссылается на функции, которые вы хотите экспортировать, из того, что вы экспортируете.