请教VS2013 引入头文件 报lnk2001求解
确定 库文件添加到工程 目录了。头文件中使用了 #define EXTERNC extern "C"EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);
cpp里面调用VCI_CloseDevice就报LNK2001。 链接器的命令行里,有没有加 XXXX.lib ? 连接器linker,输入input,添加了xxx.lib t3486784401 发表于 2023-4-6 01:23
链接器的命令行里,有没有加 XXXX.lib ?
(引用自2楼)
加了,cpp里也加了#pragma comment(lib, "xxx.lib")。无效 在 VS 的控制台里,用 dumpbin /export 指令查看下最终的 dll 文件,确认接口名称正确;
然后用 LoadLibrary 和 GetProcAddress 接口动态加载下 dll,看是否能返回有效的函数地址。
这两个确认后,基本就能排除是否是函数名的问题了。感觉像是头文件没有调用正确。 修改配置时选择的平台, Debug/Release 版本和编译时选择的是否相同?
x86/x64 + Debug/Release 在项目文件里会有 4 份配置值,有时修改时容易只修改其中一部分
t3486784401 发表于 2023-4-6 15:20
在 VS 的控制台里,用 dumpbin /export 指令查看下最终的 dll 文件,确认接口名称正确;
然后用 LoadLibrar ...
(引用自5楼)
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.
LINK : warning LNK4044: unrecognized option '/export'; ignored
Dump of file ControlCAN.dll
File Type: DLL
Summary
1D5000 .data
5000 .rdata
3000 .reloc
1000 .rsrc
E000 .text
D:\>dumpbin /exports ControlCAN.dll
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.
Dump of file ControlCAN.dll
File Type: DLL
Section contains the following exports for ControlCAN_l.dll
00000000 characteristics
63F41B14 time date stamp Tue Feb 21 09:15:00 2023
0.00 version
1 ordinal base
74 number of functions
74 number of names
ordinal hint RVA name
1 0 00008970 ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@ABV01@@Z
2 1 00008900 ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@XZ
3 2 00008250 ??0CSerialPort@itas109@@QAE@ABV01@@Z
4 3 0000AD80 ??0CSerialPort@itas109@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
5 4 0000ACD0 ??0CSerialPort@itas109@@QAE@XZ
6 5 00008BF0 ??1?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@UAE@XZ
7 6 0000AE30 ??1CSerialPort@itas109@@UAE@XZ
8 7 000081E0 ??4?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEAAV01@ABV01@@Z
9 8 000082D0 ??4CSerialPort@itas109@@QAEAAV01@ABV01@@Z
10 9 00010540 ??_7?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@6B@
11 A 00010530 ??_7CSerialPort@itas109@@6B@
12 B 0000B140 ?clearError@CSerialPort@itas109@@QAEXXZ
13 C 0000AFA0 ?close@CSerialPort@itas109@@QAEXXZ
14 D 00008C70 ?disconnect_all@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXXZ
15 E 0000B240 ?getBaudRate@CSerialPort@itas109@@QBEHXZ
16 F 0000B2C0 ?getDataBits@CSerialPort@itas109@@QBE?AW4DataBits@2@XZ
17 10 0000B340 ?getFlowControl@CSerialPort@itas109@@QBE?AW4FlowControl@2@XZ
18 11 0000B120 ?getLastError@CSerialPort@itas109@@QBEHXZ
19 12 0000B280 ?getParity@CSerialPort@itas109@@QBE?AW4Parity@2@XZ
20 13 0000B1E0 ?getPortName@CSerialPort@itas109@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
21 14 0000B380 ?getReadBufferSize@CSerialPort@itas109@@QBE_JXZ
22 15 0000B300 ?getStopBits@CSerialPort@itas109@@QBE?AW4StopBits@2@XZ
23 16 0000B3E0 ?getVersion@CSerialPort@itas109@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
24 17 0000AEC0 ?init@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HW4Parity@2@W4DataBits@2@W4StopBits@2@W4FlowControl@2@_J@Z
25 18 0000AFC0 ?isOpened@CSerialPort@itas109@@QAE_NXZ
26 19 0000B410 ?onReadReady@CSerialPort@itas109@@QAEXXZ
27 1A 0000AF80 ?open@CSerialPort@itas109@@QAE_NXZ
28 1B 0000B000 ?readAllData@CSerialPort@itas109@@QAEHPAD@Z
29 1C 0000AFE0 ?readData@CSerialPort@itas109@@QAEHPADH@Z
30 1D 0000B020 ?readLineData@CSerialPort@itas109@@QAEHPADH@Z
31 1E 0000B220 ?setBaudRate@CSerialPort@itas109@@QAEXH@Z
32 1F 0000B2A0 ?setDataBits@CSerialPort@itas109@@QAEXW4DataBits@2@@Z
33 20 0000B0C0 ?setDebugModel@CSerialPort@itas109@@QAEX_N@Z
34 21 0000B3A0 ?setDtr@CSerialPort@itas109@@QAEX_N@Z
35 22 0000B320 ?setFlowControl@CSerialPort@itas109@@QAEXW4FlowControl@2@@Z
36 23 0000B100 ?setMinByteReadNotify@CSerialPort@itas109@@QAEXI@Z
37 24 0000AF60 ?setOperateMode@CSerialPort@itas109@@QAEXW4OperateMode@2@@Z
38 25 0000B260 ?setParity@CSerialPort@itas109@@QAEXW4Parity@2@@Z
39 26 0000B160 ?setPortName@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
40 27 0000B360 ?setReadBufferSize@CSerialPort@itas109@@QAEX_J@Z
41 28 0000B0E0 ?setReadTimeInterval@CSerialPort@itas109@@QAEXH@Z
42 29 0000B3C0 ?setRts@CSerialPort@itas109@@QAEX_N@Z
43 2A 0000B2E0 ?setStopBits@CSerialPort@itas109@@QAEXW4StopBits@2@@Z
44 2B 00008B00 ?signal_connect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z
45 2C 00008B80 ?signal_disconnect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z
46 2D 0000B040 ?writeData@CSerialPort@itas109@@QAEHPBDH@Z
47 2E 0000B060 ?write_N_Data@CSerialPort@itas109@@QAEHPBDH@Z
48 2F 000060C0 ChangeKLineOfWiFiBaudRate
49 30 00006170 GetDeviceSWandHWver
50 31 00005B10 GetDeviceType
51 32 00005FE0 InitKLine_Wifi
52 33 00005FC0 KeepCommunication
53 34 00006080 ReceiveKLine
54 35 00005F30 SetContinueFrameIntervalTime
55 36 00005F60 SetCtrlFrameIDandData
56 37 00005E80 SetDevType
57 38 00005EB0 SetFilterCANidArray
58 39 000060F0 SetKLineFastInitTime
59 3A 00006050 TransmitKLine
60 3B 00005D20 VCI_ClearBuffer_l
61 3C 00005B20 VCI_CloseDevice_l
62 3D 00005CF0 VCI_GetReceiveNum_l
63 3E 00005C90 VCI_GetReference_l
64 3F 00005B50 VCI_InitCAN_l
65 40 00005A70 VCI_OpenDevice_l
66 41 00005BB0 VCI_ReadBoardInfo_l
67 42 00005C60 VCI_ReadCANStatus_l
68 43 00005C30 VCI_ReadErrInfo_l
69 44 00005E20 VCI_Receive_l
70 45 00005D90 VCI_ResetCAN_l
71 46 00005CC0 VCI_SetReference_l
72 47 00005D50 VCI_StartCAN_l
73 48 00005DC0 VCI_Transmit_l
74 49 00006130 closeTCPconnect
Summary
1D5000 .data
5000 .rdata
3000 .reloc
1000 .rsrc
E000 .text
比较奇怪,头文件的函数名,怎么和这里面的函数名不一致。而且按照此VCI_CloseDevice_l()调用函数仍然报LNK2001 wudicgi 发表于 2023-4-6 15:23
修改配置时选择的平台, Debug/Release 版本和编译时选择的是否相同?
x86/x64 + Debug/Release 在项目文件 ...
(引用自6楼)
我另一个工程里用的另外的LIB是正常使用的。说明配置是正常的。只是这个LIB第一次用。 zw_7627 发表于 2023-4-7 00:01
我另一个工程里用的另外的LIB是正常使用的。说明配置是正常的。只是这个LIB第一次用。 ...
(引用自8楼)
LIB的:
D:\>dumpbin /exports ControlCAN.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.
Dump of file ControlCAN.lib
File Type: LIBRARY
Exports
ordinal name
??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@ABV01@@Z (public: __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::has_slots<class sigslot::multi_threaded_local>(class sigslot::has_slots<class sigslot::multi_threaded_local> const &))
??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@XZ (public: __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::has_slots<class sigslot::multi_threaded_local>(void))
??0CSerialPort@itas109@@QAE@ABV01@@Z (public: __thiscall itas109::CSerialPort::CSerialPort(class itas109::CSerialPort const &))
??0CSerialPort@itas109@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z (public: __thiscall itas109::CSerialPort::CSerialPort(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &))
??0CSerialPort@itas109@@QAE@XZ (public: __thiscall itas109::CSerialPort::CSerialPort(void))
??1?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@UAE@XZ (public: virtual __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::~has_slots<class sigslot::multi_threaded_local>(void))
??1CSerialPort@itas109@@UAE@XZ (public: virtual __thiscall itas109::CSerialPort::~CSerialPort(void))
??4?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEAAV01@ABV01@@Z (public: class sigslot::has_slots<class sigslot::multi_threaded_local> & __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::operator=(class sigslot::has_slots<class sigslot::multi_threaded_local> const &))
??4CSerialPort@itas109@@QAEAAV01@ABV01@@Z (public: class itas109::CSerialPort & __thiscall itas109::CSerialPort::operator=(class itas109::CSerialPort const &))
??_7?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@6B@ (const sigslot::has_slots<class sigslot::multi_threaded_local>::`vftable')
??_7CSerialPort@itas109@@6B@ (const itas109::CSerialPort::`vftable')
?clearError@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::clearError(void))
?close@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::close(void))
?disconnect_all@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXXZ (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::disconnect_all(void))
?getBaudRate@CSerialPort@itas109@@QBEHXZ (public: int __thiscall itas109::CSerialPort::getBaudRate(void)const )
?getDataBits@CSerialPort@itas109@@QBE?AW4DataBits@2@XZ (public: enum itas109::DataBits __thiscall itas109::CSerialPort::getDataBits(void)const )
?getFlowControl@CSerialPort@itas109@@QBE?AW4FlowControl@2@XZ (public: enum itas109::FlowControl __thiscall itas109::CSerialPort::getFlowControl(void)const )
?getLastError@CSerialPort@itas109@@QBEHXZ (public: int __thiscall itas109::CSerialPort::getLastError(void)const )
?getParity@CSerialPort@itas109@@QBE?AW4Parity@2@XZ (public: enum itas109::Parity __thiscall itas109::CSerialPort::getParity(void)const )
?getPortName@CSerialPort@itas109@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ (public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall itas109::CSerialPort::getPortName(void)const )
?getReadBufferSize@CSerialPort@itas109@@QBE_JXZ (public: __int64 __thiscall itas109::CSerialPort::getReadBufferSize(void)const )
?getStopBits@CSerialPort@itas109@@QBE?AW4StopBits@2@XZ (public: enum itas109::StopBits __thiscall itas109::CSerialPort::getStopBits(void)const )
?getVersion@CSerialPort@itas109@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ (public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall itas109::CSerialPort::getVersion(void))
?init@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HW4Parity@2@W4DataBits@2@W4StopBits@2@W4FlowControl@2@_J@Z (public: void __thiscall itas109::CSerialPort::init(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,enum itas109::Parity,enum itas109::DataBits,enum itas109::StopBits,enum itas109::FlowControl,__int64))
?isOpened@CSerialPort@itas109@@QAE_NXZ (public: bool __thiscall itas109::CSerialPort::isOpened(void))
?onReadReady@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::onReadReady(void))
?open@CSerialPort@itas109@@QAE_NXZ (public: bool __thiscall itas109::CSerialPort::open(void))
?readAllData@CSerialPort@itas109@@QAEHPAD@Z (public: int __thiscall itas109::CSerialPort::readAllData(char *))
?readData@CSerialPort@itas109@@QAEHPADH@Z (public: int __thiscall itas109::CSerialPort::readData(char *,int))
?readLineData@CSerialPort@itas109@@QAEHPADH@Z (public: int __thiscall itas109::CSerialPort::readLineData(char *,int))
?setBaudRate@CSerialPort@itas109@@QAEXH@Z (public: void __thiscall itas109::CSerialPort::setBaudRate(int))
?setDataBits@CSerialPort@itas109@@QAEXW4DataBits@2@@Z (public: void __thiscall itas109::CSerialPort::setDataBits(enum itas109::DataBits))
?setDebugModel@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setDebugModel(bool))
?setDtr@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setDtr(bool))
?setFlowControl@CSerialPort@itas109@@QAEXW4FlowControl@2@@Z (public: void __thiscall itas109::CSerialPort::setFlowControl(enum itas109::FlowControl))
?setMinByteReadNotify@CSerialPort@itas109@@QAEXI@Z (public: void __thiscall itas109::CSerialPort::setMinByteReadNotify(unsigned int))
?setOperateMode@CSerialPort@itas109@@QAEXW4OperateMode@2@@Z (public: void __thiscall itas109::CSerialPort::setOperateMode(enum itas109::OperateMode))
?setParity@CSerialPort@itas109@@QAEXW4Parity@2@@Z (public: void __thiscall itas109::CSerialPort::setParity(enum itas109::Parity))
?setPortName@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z (public: void __thiscall itas109::CSerialPort::setPortName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >))
?setReadBufferSize@CSerialPort@itas109@@QAEX_J@Z (public: void __thiscall itas109::CSerialPort::setReadBufferSize(__int64))
?setReadTimeInterval@CSerialPort@itas109@@QAEXH@Z (public: void __thiscall itas109::CSerialPort::setReadTimeInterval(int))
?setRts@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setRts(bool))
?setStopBits@CSerialPort@itas109@@QAEXW4StopBits@2@@Z (public: void __thiscall itas109::CSerialPort::setStopBits(enum itas109::StopBits))
?signal_connect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::signal_connect(class sigslot::_signal_base<class sigslot::multi_threaded_local> *))
?signal_disconnect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::signal_disconnect(class sigslot::_signal_base<class sigslot::multi_threaded_local> *))
?writeData@CSerialPort@itas109@@QAEHPBDH@Z (public: int __thiscall itas109::CSerialPort::writeData(char const *,int))
?write_N_Data@CSerialPort@itas109@@QAEHPBDH@Z (public: int __thiscall itas109::CSerialPort::write_N_Data(char const *,int))
_ChangeKLineOfWiFiBaudRate
_GetDeviceSWandHWver
_GetDeviceType
_InitKLine_Wifi
_KeepCommunication
_ReceiveKLine
_SetContinueFrameIntervalTime
_SetCtrlFrameIDandData
_SetDevType
_SetFilterCANidArray
_SetKLineFastInitTime
_TransmitKLine
_VCI_ClearBuffer_l
_VCI_CloseDevice_l
_VCI_GetReceiveNum_l
_VCI_GetReference_l
_VCI_InitCAN_l
_VCI_OpenDevice_l
_VCI_ReadBoardInfo_l
_VCI_ReadCANStatus_l
_VCI_ReadErrInfo_l
_VCI_Receive_l
_VCI_ResetCAN_l
_VCI_SetReference_l
_VCI_StartCAN_l
_VCI_Transmit_l
_closeTCPconnect
Summary
D2 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
12 .idata$6
D:\> 到底是动态库还是静态库,怎么 dumpbin 的文件一个是 .dll 一个是 .lib
符号和原始函数名不一致是因为 name mangling
https://zh.wikipedia.org/wiki/%E5%90%8D%E5%AD%97%E4%BF%AE%E9%A5%B0
wudicgi 发表于 2023-4-7 00:43
到底是动态库还是静态库,怎么 dumpbin 的文件一个是 .dll 一个是 .lib
符号和原始函数名不一致是因为 nam ...
(引用自10楼)
有三个文件,.h,.lib,.dll,动态库。维基百科没梯子上不去{:sweat:} void *p=NULL;
p=LoadLibrary("XXX.dll");
返回值是0 zw_7627 发表于 2023-4-7 00:06
LIB的:
D:\>dumpbin /exports ControlCAN.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
(引用自9楼)
我查看了手头的一些库,的确 lib 当中的函数名应该比 dll 当中多一个前置下划线,最终调用的函数名以 dll 为准。
至于 LoadLibrary 失败的话,考虑在 Unicode 环境下(默认VS选项)使用
::LoadLibrary(_T("C:\\XXX\\YY.dll"));
这样的完整路径,并强制使用 Unicode 字符串
t3486784401 发表于 2023-4-7 23:19
我查看了手头的一些库,的确 lib 当中的函数名应该比 dll 当中多一个前置下划线,最终调用的函数名以 dll ...
(引用自13楼)
void *p=NULL;
p = LoadLibrary(_T("ControlCAN_l.dll"));
DWORD error_id=GetLastError();
p值不为0了,error_id 为0,dll库成功 加载了。但是引用VCI_CloseDevice()函数还是报LNK2001 zw_7627 发表于 2023-4-8 00:11
void *p=NULL;
p = LoadLibrary(_T("ControlCAN_l.dll"));
DWORD error_id=GetLastError();
(引用自14楼)
把头文件改成VCI_CloseDevice_l(),再引用也是一样。{:cry:} zw_7627 发表于 2023-4-8 00:11
void *p=NULL;
p = LoadLibrary(_T("ControlCAN_l.dll"));
DWORD error_id=GetLastError();
(引用自14楼)
LoadLibrary 之后是 GetProcAddress,这其中应该能定位到目标函数名。
然而这个过程是动态 dll 调用,与编译时静态调用完全是两个方向。
目测是头文件 / lib 有问题,实在不行就考虑动态调用吧 LZ 把工程文件删一删,只留下和问题相关的东西后打个包传上来吧。
问题应该不复杂,但不了解的话,关键信息容易被漏掉,这么讨论难出结果。
本帖最后由 zw_7627 于 2023-4-9 00:43 编辑
wudicgi 发表于 2023-4-8 18:17
LZ 把工程文件删一删,只留下和问题相关的东西后打个包传上来吧。
问题应该不复杂,但不了解的话,关键信息 ...
(引用自17楼)
工程上传文件限制在16M了,打包了编译文件{:handshake:}
void CTTDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
VCI_CloseDevice_l(1,0); //编译不过
} zw_7627 发表于 2023-4-9 00:42
工程上传文件限制在16M了,打包了编译文件
void CTTDlg::OnBnClickedButton1()
(引用自18楼)
传上来的压缩包里没有 ControlCAN.h 和 ControlCAN.lib
我从这下了份 x86 的先用着,可能和你的版本不一样
https://github.com/JloveU/ControlCAN/tree/master/ControlCANx86
在把 CTTDlg::OnBnClickedButton1() 中的调用改成 VCI_CloseDevice(1,0); 之后,在 VS2017 中是能编译通过的
我还在 stdafx.h 中添加了一行 #define no_init_all deprecated 是因为 VS2017 的 bug, 你用的 VS2013 应该没这个问题
https://stackoverflow.com/questions/61485127/including-windows-h-causes-unknown-attributeno-init-all-error
我把我编译结果的二进制文件,和 ControlCAN.h/.lib 以及修改了的 2 个源文件都传上来,你可以对比看看
zw_7627 发表于 2023-4-9 00:42
工程上传文件限制在16M了,打包了编译文件
void CTTDlg::OnBnClickedButton1()
(引用自18楼)
我刚注意到你的压缩包里有 123.dll/.lib/.h, 我改名成 ControlCAN.dll/.lib/.h 后又试了一下
问题和函数声明里的调用约定有关
首先有个问题,就是 ControlCAN.dll/.lib/.h 和 ControlCAN_l.dll/.lib/.h 应该是两套东西
但是我看现在的 .dll 和 .lib 里以 VCI_ 开头的函数符号都是以 _l 结尾的,但 .h 文件里的函数名结尾又没有 _l
也就是说现在这个 .h 和 .dll/.lib 文件不是一套的
我看你发的压缩包里的 .h 是这样的:
EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
EXTERNC DWORD __stdcall VCI_CloseDevice_l(DWORD DeviceType, DWORD DeviceInd);
EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);
应该是自己把原来的 VCI_CloseDevice 给改成 VCI_CloseDevice_l 了,单就这个函数来说,把它改成
EXTERNC DWORD __cdecl VCI_CloseDevice_l(DWORD DeviceType, DWORD DeviceInd);
链接就能成功了
你遇到的问题,首先应该是 .h 文件不对,其次是 stdcall 调用约定时 name mangling 之后的符号名是 _function@nnn 这样的
而默认的 cdecl 调用约定出来的符号名是_function 这样的,对应不上自然链接会找不到
https://www.cnblogs.com/lidabo/archive/2012/11/21/2781484.html
wudicgi 发表于 2023-4-9 11:45
我刚注意到你的压缩包里有 123.dll/.lib/.h, 我改名成 ControlCAN.dll/.lib/.h 后又试了一下
问题和函数 ...
(引用自20楼)
{:victory:} 的确编译通过了,明天调试下{:handshake:} 。
页:
[1]