2014-01-10 6 views
0

У меня есть сторонний C++ .lib, который я хотел бы использовать в приложении C#.Как ссылаться на библиотеку C++ без класса/пространства имен?

Мое намерение состоит в том, чтобы написать управляемую CML-оболочку .dll для .lib, а затем включить эту оболочку dll в мое приложение C#, используя процесс примерно как the one outlined at this link.

Заголовочный файл для .lib не указывает на объявление класса или пространства имен, только имена методов:

int CheckNamedVariable(const char* _name); 
int RegisterNamedVariable(const char* _name); 
double GetNamedVariableValue(int _id); 
double GetNamedVariableTypedValue(int _id, int _units); 
void SetNamedVariableValue(int _id, double _value); 
... (etc) 

я проверил Либерал с Dumpbin/экспорта, чтобы увидеть, если я мог бы почерпнуть дополнительную информацию, и получил следующее:

File Type: LIBRARY 

    Exports 

     ordinal name 

        [email protected]@[email protected] (double __cdecl AircraftVarGet(int,int,int)) 
        [email protected]@[email protected] (int __cdecl CheckNamedVariable(char const *)) 
        [email protected]@YGXXZ (void __stdcall DLLStart(void)) 
        [email protected]@YGXXZ (void __stdcall DLLStop(void)) 
        [email protected]@[email protected] (int __cdecl GetAircraftVarEnum(char const *)) 
        [email protected]@[email protected]@@Z (double __cdecl GetModuleVar(enum GAUGE_TOKEN)) 
        [email protected]@[email protected] (char const * __cdecl GetNameOfNamedVariable(int)) 
        [email protected]@[email protected] (double __cdecl GetNamedVariableTypedValue(int,int)) 
        [email protected]@[email protected] (double __cdecl GetNamedVariableValue(int)) 
        [email protected]@[email protected] (int __cdecl GetUnitsEnum(char const *)) 
        [email protected]@[email protected] (int __cdecl IsPanelWindowVisibleIdent(unsigned int)) 
        [email protected]@[email protected]@A (struct PANELS * Panels) 
        [email protected]@[email protected] (int __cdecl RegisterNamedVariable(char const *)) 
        [email protected]@[email protected] (void __cdecl SendKeyEvent(unsigned int,unsigned int)) 
        [email protected]@[email protected] (void __cdecl SetNamedVariableTypedValue(int,double,int)) 
        [email protected]@[email protected] (void __cdecl SetNamedVariableValue(int,double)) 
        _ImportTable 
        _Linkage 

    Summary 

      ED .debug$S 
      14 .idata$2 
      14 .idata$3 
      4 .idata$4 
      4 .idata$5 
      1A .idata$6 

в моем управляемом проекте обертки, я могу указать на вход Linker в .lib, но я не знаю, как назвать методы в Lib (учебник я связан с используют пространств имен и классов). Если бы это была простая старая DLL в проекте C#/VB, я мог бы просмотреть браузер объектов и получить представление о том, как вызвать библиотеку.

Но, учитывая мое незнание C++, я в темноте. Любая помощь оценивается.

EDIT: Я пытался просто создать методы с тем же именем, что и методы, перечисленные в заголовке, например:

int VariableExporter::IsPanelWindowVisibleIdent(unsigned int panel_id) 
{ 
    return IsPanelWindowVisibleIdent(panel_id); 
} 

Это не делает то, что я надеюсь, что это просто рекурсивно, называющая себя (пока у него не будет - дождитесь его - переполнение стека).

Затем я попытался переименовать метод обертку, как это:

int VariableExporter::IsPanelWindowVisibleIdent_New_Name(unsigned int panel_id) 
{ 
    return IsPanelWindowVisibleIdent(panel_id); 
} 

Теперь, хотя проект C++ .DLL и # проект C и компиляции, то C# проект бросает исключение FileNotFound, когда он пытается загрузить его. DLL.

+1

Используйте 'extern 'C'' для символов, экспортированных в C# .... (или в C). –

+0

Прошу простить незнание того, что я прошу, но ... разве это не относится к исходному коду для .lib? У меня нет доступа к этому источнику ... просто двоичная библиотека и заголовочный файл. – GojiraDeMonstah

ответ

0

Первое, вызвать глобальную функцию уровня необходимо использовать разрешения области видимости оператора:

int VariableExporter::IsPanelWindowVisibleIdent(unsigned int panel_id) 
{ 
    return ::IsPanelWindowVisibleIdent(panel_id); 
} 

Там нет необходимости (по крайней мере, для этого простого случая), чтобы переименовать метод.

Во-вторых, для проблемы с DLL-not-found проверьте, что DLL присутствует в пути bin вашего приложения C# . Также проверьте, что сама обертка-DLL является загружаемой (используйте Dependency Walker). Также убедитесь, что бит-версия оболочки DLL и C# приложение также соответствует. 64-разрядное приложение не может загрузить 32-разрядную DLL (и наоборот).

Смежные вопросы