链接到不带.lib的.dll文件 [英] Linking to a .dll file without the .lib

查看:70
本文介绍了链接到不带.lib的.dll文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将一些Delphi代码重写为C ++,并且需要链接到动态库 TMLComm2004.dll .事实证明,我们没有任何 .lib 文件,因此我们决定使用以下命令行生成该文件:

  dumpbin/EXPORTS C:\ Users \ fayard \ Desktop \ TMLComm2004.dll>C:\ Users \ fayard \ Desktop \ TMLComm2004.txt 

我们获得以下文件

  Microsoft(R)COFF/PE Dumper版本14.00.24215.1版权所有(C)Microsoft Corporation.版权所有.文件C:\ Users \ fayard \ Desktop \ TMLComm2004.dll的转储档案类型:DLL本节包含TMLcomm.dll的以下导出00000000特征401F6AD5时间日期戳2004年2月3日星期二10:33:090.00版本1个序数基数27种功能27个名字顺序提示RVA名称1 0 00001122 _MSK_COFFDownloadFlash @ 162 1 0000114F _MSK_COFF下载RAM @ 203 2 0000106E _MSK_CheckSum @ 124 3 00001172 _MSK_CloseComm @ 05 4 00001190 _MSK_GetActiveBoard @ 46 5 0000109B _MSK_GetBoardInfo @ 87 6 0000104B _MSK_GetBytesCountInQueue @ 08 7 0000119A _MSK_GetChar @ 49 8 000010E6 _MSK_GetCharNoWait @ 410 9 000011A4 _MSK_GetCommBaudRate @ 411个000010DC _MSK_GetHostBoard @ 412 B 0000108C _MSK_OpenComm @ 1613 C 000011DB _MSK_ReceiveData @ 1614 D 000011CC _MSK_ReceiveMessage @ 415 E 0000105A _MSK_RegisterReceiveUnsolicitedMsgHandler @ 416 F 000011AE _MSK_ResetMSKBoard @ 017 10 00001037 _MSK_SendChar @ 418 11 000010EB _MSK_SendData @ 1619 12 0000126C _MSK_SendMessage @ 420 13 0000128F _MSK_SetActiveBoard @ 421 14 00001136 _MSK_SetB0BlockAsData @ 422 15 0000100A _MSK_SetBoardBaudRate @ 423 16 00001019 _MSK_SetCharMode @ 424 17 00001168 _MSK_SetCommBaudRate @ 425 18 00001050 _MSK_SetDebugWindow @ 826 19 00001276 _MSK_SetHostBoard @ 427 1A 00001046 _MSK_UpdateCommTimeouts @ 0概括C000 .data3000 .idata6000 .rdata4000 .reloc21000 .rsrc3E000 .text2000 shdata 

然后,我们编辑了 TMLComm2014.txt 文件,并将其更改为 .def 文件,并删除了@xx.该文件如下所示:

  EXPORTS_MSK_COFFDownloadFlash... 

然后,我们生成具有以下内容的 .lib 文件:

  lib/def:C:\Users\fayard\Desktop\TMLComm2004.def/out:C:\Users\fayard\Desktop\TMLComm2004.lib 

我们编译以下程序:

 外部"C" {bool MSK_OpenComm(unsigned char a,unsigned short b,bool c,unsigned char d);}... 

当我们编译并链接到 .lib 时,会出现错误:

  LNK2019函数中引用的未解析外部符号_MSK_OpenComm ... 

我怎么办?

更新

我已成功编译为:

 外部"C" {布尔__stdcall MSK_OpenComm(unsigned char a,unsigned short b,bool c,unsigned char d);} 

但是现在问题出在链接时.我从命令行中感到困惑,我有:

  ====================================================dumpbin/headers TMLComm.lib版本:0机器:14C(x86)TimeDateStamp:5964C365 2017年7月11日星期二14:24:05数据大小:00000022DLL名称:TMLComm2004.dll符号名称:__MSK_OpenComm @ 16类型:代码名称类型:无前缀提示:11名称:_MSK_OpenComm @ 16==================================================dumpbin/exports TMLComm.dll12 B 0000108C _MSK_OpenComm @ 16================================================== 

现在编译正常,但问题出在链接时:

 <代码>链接tmlcomm.obj Motor.obj main.obj TMLComm.lib/out:main.exeMicrosoft(R)增量链接器版本14.00.24215.1版权所有(C)Microsoft Corporation.版权所有.tmlcomm.obj:错误LNK2019:函数"bool __cdecl msk_opencomm(unsigned char,unsigned short,bool,unsigned char)"中引用的未解析的外部符号_MSK_OpenComm @ 16(?msk_opencomm @@ YA_NEG_NE @ Z)Teclis.exe:致命错误LNK1120:1个未解决的外部组件 

解决方案

看看Microsoft的修饰名称的文档.对于C,前导下划线和后跟 @< number> 表示 stdcall 调用约定,这与标准的 cdecl 不同./p>

因此,您应该只修改符号以 @< number> 结尾的所有函数的声明:

 外部"C" {__stdcall bool MSK_OpenComm(unsigned char a,unsigned short b,bool c,unsigned char d);} 

我不确定是否应该从 .def 文件中删除 @< number> 部分是否正确,我对此表示怀疑,但只需尝试一下.

通过我使用 MinGW 工具创建 .def 文件( gendef )的工具进行的实验,该文件的名称在 .def中应该包括前划线,但在末尾包含 @< number> 部分.因此,对于此示例函数, .def 应该具有以下行:

  MSK_OpenComm @ 16 

MinGW 附带的工具是手动创建这些必需文件的替代方法.您可以执行以下操作:

  gendef foobar.dll#生成.defdlltool -d foobar.def -l foobar.lib#生成导入库 

根据您的评论,您可能需要手动编辑 .def 文件 gendef ,该文件将包含以下行:/p>

  MSK_OpenComm @ 16 = _MSK_OpenComm @ 16 

似乎 gendef 可能会感到困惑,因为dll会导出意想不到的装饰名称.


使用导入库时,将具有静态存根"的名称,类似于DLL的实际导出符号,但带有 __ imp __ .为了解决这个问题,您需要在声明中添加另一个属性:

 外部"C" {__declspec(dllimport)__stdcall bool MSK_OpenComm(无符号字符a,无符号短字符b,布尔c,无符号字符d);} 

I need to rewrite some Delphi code to C++ and we need to link to the dynamic library TMLComm2004.dll. It turns out that we don't have any .lib file so we decided to generate it, using the following command lines:

dumpbin /EXPORTS C:\Users\fayard\Desktop\TMLComm2004.dll > C:\Users\fayard\Desktop\TMLComm2004.txt

We obtain the following file

Microsoft (R) COFF/PE Dumper Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\Users\fayard\Desktop\TMLComm2004.dll

File Type: DLL

  Section contains the following exports for TMLcomm.dll

    00000000 characteristics
    401F6AD5 time date stamp Tue Feb  3 10:33:09 2004
        0.00 version
          1 ordinal base
          27 number of functions
          27 number of names

    ordinal hint RVA      name

          1    0 00001122 _MSK_COFFDownloadFlash@16
          2    1 0000114F _MSK_COFFDownloadRAM@20
          3    2 0000106E _MSK_CheckSum@12
          4    3 00001172 _MSK_CloseComm@0
          5    4 00001190 _MSK_GetActiveBoard@4
          6    5 0000109B _MSK_GetBoardInfo@8
          7    6 0000104B _MSK_GetBytesCountInQueue@0
          8    7 0000119A _MSK_GetChar@4
          9    8 000010E6 _MSK_GetCharNoWait@4
         10    9 000011A4 _MSK_GetCommBaudRate@4
         11    A 000010DC _MSK_GetHostBoard@4
         12    B 0000108C _MSK_OpenComm@16
         13    C 000011DB _MSK_ReceiveData@16
         14    D 000011CC _MSK_ReceiveMessage@4
         15    E 0000105A _MSK_RegisterReceiveUnsolicitedMsgHandler@4
         16    F 000011AE _MSK_ResetMSKBoard@0
         17   10 00001037 _MSK_SendChar@4
         18   11 000010EB _MSK_SendData@16
         19   12 0000126C _MSK_SendMessage@4
         20   13 0000128F _MSK_SetActiveBoard@4
         21   14 00001136 _MSK_SetB0BlockAsData@4
         22   15 0000100A _MSK_SetBoardBaudRate@4
         23   16 00001019 _MSK_SetCharMode@4
         24   17 00001168 _MSK_SetCommBaudRate@4
         25   18 00001050 _MSK_SetDebugWindow@8
         26   19 00001276 _MSK_SetHostBoard@4
         27   1A 00001046 _MSK_UpdateCommTimeouts@0

  Summary

        C000 .data
        3000 .idata
        6000 .rdata
        4000 .reloc
       21000 .rsrc
       3E000 .text
        2000 shdata

Then, we have edited the TMLComm2014.txt file and changed it to a .def file with the @xx removed. The file looks like:

EXPORTS
_MSK_COFFDownloadFlash
...

Then, we generate a .lib file with:

lib /def:C:\Users\fayard\Desktop\TMLComm2004.def /out:C:\Users\fayard\Desktop\TMLComm2004.lib

We compile the following program:

extern "C" {
  bool MSK_OpenComm(unsigned char a, unsigned short b, bool c, unsigned char d);
}

...

When we compile and link against the .lib, we get an error:

LNK2019 unresolved external symbol _MSK_OpenComm referenced in function...

What's wrong with what I do?

Update

I have managed to compile with:

extern "C" {
  bool __stdcall MSK_OpenComm(unsigned char a, unsigned short b, bool c, unsigned char d);
}

but now the problem is at link time. I am puzzled as from command line, I have:

==================================================
dumpbin /headers TMLComm.lib

  Version      : 0
  Machine      : 14C (x86)
  TimeDateStamp: 5964C365 Tue Jul 11 14:24:05 2017
  SizeOfData   : 00000022
  DLL name     : TMLComm2004.dll
  Symbol name  : __MSK_OpenComm@16
  Type         : code
  Name type    : no prefix
  Hint         : 11
  Name         : _MSK_OpenComm@16

==================================================
dumpbin /exports TMLComm.dll

         12    B 0000108C _MSK_OpenComm@16

==================================================

Compilation goes fine now, but the problem is at link time:

link tmlcomm.obj Motor.obj main.obj TMLComm.lib /out:main.exe


Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

tmlcomm.obj : error LNK2019: unresolved external symbol _MSK_OpenComm@16 referenced in function "bool __cdecl msk_opencomm(unsigned char,unsigned short,bool,unsigned char)" (?msk_opencomm@@YA_NEG_NE@Z)
Teclis.exe : fatal error LNK1120: 1 unresolved externals

解决方案

Have a look at Microsoft's documentation of decorated names. For C, a leading underscore and a trailing @<number> denotes the stdcall calling convention, which is different from the standard cdecl.

So, you should just modify your declarations for all functions where the symbol ends with @<number>:

extern "C" {
  __stdcall bool MSK_OpenComm(unsigned char a, unsigned short b, bool c, unsigned char d);
}

I'm not sure whether stripping the @<number> part from the .def file is the right thing to do, I doubt it, but just try it out.

From my experiment with MinGWs tool for creating a .def file (gendef), the name in the .def should not include the leading underscore, but it should include the @<number> part at the end. So for this example function, the .def should have the following line:

MSK_OpenComm@16

An alternative to manually creating these required files are the tools that come with MinGW. You could just do the following:

gendef foobar.dll                     # generates the .def
dlltool -d foobar.def -l foobar.lib   # generates the import library

Based on your comments, you might need to manually edit the .def file gendef is giving you to contain lines like this:

MSK_OpenComm@16=_MSK_OpenComm@16

It seems that gendef could be confused because the dll exports decorated names which isn't expected.


When using an import library, this will have "static stubs" named like the actual exported symbols of the DLL, but with __imp__ prepended. To account for this, you need yet another attribute in your declarations:

extern "C" {
  __declspec(dllimport) __stdcall bool MSK_OpenComm(unsigned char a, unsigned short b, bool c, unsigned char d);
}

这篇关于链接到不带.lib的.dll文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆