[英]Linker warning “second definition ignored” when including two libraries with same function names
上下文
我正在開發一個旨在將某些命令發送到設備的項目。 每個設備都可以與dll接口(例如deviceADll.h,deviceBDll.h),Dll不是由我編程的,也不能以任何方式修改它們。 我負責將DeviceB集成到項目中,對項目結構的改動很小。 我知道結構可能不是最佳和/或設計得很好,所以我願意就這個問題提出建議,作為最后的解決方案。
由於設備非常相似,所有Dll功能都具有相同的名稱,並且通常是相同的原型。
也是因為這個,我創建了一個父類(Device_ts.h),DeviceA_ts.h和DeviceB_ts.h繼承了它(我也有一個工廠的工廠類,但我不認為它與我的問題有關) 。
問題
當我嘗試包含兩個Dll時出現問題:項目編譯,但我得到了
Warning 60 warning LNK4006: Connect@12 already defined in DeviceA.lib(DeviceA.dll); second definition ignored C:\\project_path\\DeviceB.lib(DeviceB.dll) Project_Name
接下來是
Warning 61 warning LNK4006: __imp__Connect@12 already defined in DeviceA.lib(DeviceA.dll); second definition ignored C:\\project_path\\DeviceB.lib(DeviceB.dll) Project_Name
和a
Warning 62 warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library C:\\project_path\\DeviceB.lib(DeviceB.dll) Project_Name
有沒有人經歷過類似的情況? 我是否應該忽略這些警告,否則我將無法調用DeviceB.h
函數,因為它們的定義被忽略了?
我正在使用Visual Studio 2010,我正在編寫的Device_ts.h
庫是一個靜態庫,所有項目的參數(例如/ MD,包括目錄,依賴項,MFC等)都是根據我在研究中找到的正確設置的問題。
碼
include和代碼看起來像這樣(我只會顯示導致警告的一個函數,因為我在50個函數上得到了相同的錯誤):
DeviceADll.h
#ifndef DEVICEA_H__
#define DEVICEA_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
namespace DeviceA
{
// some struct definition that don't cause the linker warnings
//...
// function definitions
extern "C" HANDLE PASCAL EXPORT Connect( HANDLE h_devA, const char *ip);
// ...
} // namespace DeviceA
DeviceBDll.h
#ifndef DEVICEB_H__
#define DEVICEB_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
namespace DeviceB
{
// some struct definition that don't cause the linker warnings
//...
// function definitions
extern "C" HANDLE PASCAL EXPORT Connect( HANDLE h_devB, const char *ip);
// ...
} // namespace DeviceB
Device_ts.h
#ifndef DEVICE_FCT_H_
#define DEVICE_FCT_H_
#ifndef EXPORT
#define EXPORT
#endif
#if _MSC_VER > 1000
#pragma once
#endif
#include "DeviceADll.h"
#include "DeviceBDll.h"
class CDevice {
public:
virtual BOOL Connect(char *ip_addr) = 0;
};
#endif DEVICE_FCT_H_
這是使用LoadLibrary()
和GetProcAddress()
進行手動DLL加載的一個很好的用例。
你必須為這樣查找的每個函數管理一個函數指針,這有點痛苦,但是繞過操作系統的dll加載會給你很大的靈活性。
另請注意,使用此方法時不需要鏈接DLL,dll綁定是100%運行時,並且根本不涉及鏈接器。
這是一個例子:
typedef void (*connect_fn)(HANDLE, const char*);
connect_fn connect_a;
connect_fn connect_b;
int main()
{
HINSTANCE dll_a = LoadLibrary("path_to_dll_a.dll");
HINSTANCE dll_b = LoadLibrary("path_to_dll_b.dll");
if (!dll_a || !dll_b) {
return 1;
}
connect_a = (connect_fn)GetProcAddress(dll_a , "Connect");
connect_b = (connect_fn)GetProcAddress(dll_b , "Connect");
// connect_a and connect_b can now be used.
return 0;
}
編輯:基本上,我建議你將設備DLL視為插件,而不是動態庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.