我看到了像这样的Qt源代码:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Run Code Online (Sandbox Code Playgroud)
哪个Q_CORE_EXPORT
宏定义如下:
define Q_DECL_IMPORT __declspec(dllimport)
Run Code Online (Sandbox Code Playgroud)
那__declspec(dllimport)
真正意味着什么?
在使用server.dll和client.exe的项目中,我dllexport
从服务器dll编辑了一个服务器符号,而不是将其 dllimport
编辑到客户端exe中.
仍然,应用程序链接,并启动,没有任何问题.是dllimport
不需要的,那么???
细节:
我有这个'服务器'DLL:
// server.h
#ifdef SERVER_EXPORTS
#define SERVER_API __declspec(dllexport)
#else
#define SERVER_API // =====> not using dllimport!
#endif
class SERVER_API CServer {
static long s;
public:
CServer();
};
// server.cpp
CServer::CServer(){}
long CServer::s;
Run Code Online (Sandbox Code Playgroud)
这个客户端可执行文件
#include <server.h>
int main() {
CServer s;
}
Run Code Online (Sandbox Code Playgroud)
服务器命令行:
cl.exe /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL"
/D "SERVER_EXPORTS" /D "_UNICODE" /D "UNICODE" /D "_WINDLL"
/Gm /EHsc /RTC1 /MDd /Yu"stdafx.h"
/Fp"Debug\server.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb"
/W3 /nologo …
Run Code Online (Sandbox Code Playgroud) 我的项目通过几个静态库构建,这些库应该链接到主dll库,因此获得一个单独的dll.
使用__declspec(dllexport)
属性不会导致静态库的指定函数出现到dll,库根本没有与dll链接.
然后我尝试将每个库构建为共享以获取导出函数的正确名称,并基于它们创建.def文件.使用.def文件导致结果.
应该__declspec(dllexport)
和.def-file
我的情况一样行事吗?
是否可以从源生成.def文件?由于我有C++代码,因为API中的修改和存在类,我不能自己编写.def文件,上面描述的临时生成的dll方法与生产不一致.
我想详细解释一下我项目的结构.该解决方案包含一些项目(模块).
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
Run Code Online (Sandbox Code Playgroud)
每个子项目都弱于其他子项目,让我们假设它们之间没有联系是为了清晰.每个模块都有自己的公共接口.我想将所有模块作为单个动态库,所以我的工件是dynamic_lib.dll
,但实际上静态库没有与它链接.
我需要在C++中创建一些共享库,并使用linux作为我的开发人员操作系统.我知道如果我想通过dlsym
/ 加载它们,我需要使符号可见LoadLibrary
.所以在linux中我的所有符号都遵循这种模式:
extern "C" [[gnu::visibility("default")]] void f();
Run Code Online (Sandbox Code Playgroud)
我使用了启用了C++ 11的clang,我能够加载f
我的宿主程序.当我移动到Windows时,我使用GCC 4.8.2启用了C++ 11,并且该模式也适用于Windows机器LoadLibrary
.(我需要使用C++ 11来获取新的属性语法).我知道在Windows上我需要用来__declspec(dllexport)
从共享库中导出符号.所以现在怎么办?是__declspec(dllexport)
不是不再需要?
编辑:
我发现在这里,那些是同义词(我认为),所以问题是,是否有一个[[gnu::attribute]]
用于__declspec(dllimport)
避免使用宏和ifdef
S代表具体的目标?
当调用C++算法(如copy_if,transform等,它们将一元或二元函数作为最后一个参数)时,我可以传递一个像atoi或tolower这样的C库函数.
例如,以下调用工作正常并给出正确的输出(在ideone中尝试)
1) transform (foo, foo+5, bar, atoi);
2) transform (foo, foo+5, bar, ptr_fun(atoi));
3) transform(s.begin(),s.end(),s.begin(), static_cast<int (*)(int)>(tolower));
Run Code Online (Sandbox Code Playgroud)
这种用法是否可以保证适用于所有C++编译器?
用C++思考的这本书提到"这适用于一些编译器,但并不是必须的." 提到的原因是(据我所知),转换是C++函数,并期望它的最后一个参数具有相同的调用约定.
本书还提出了解决此问题的方法,即在单独的cpp文件中创建这样的包装函数,并且不包含iostreams头文件.
// tolower_wrapper.cpp
string strTolower(string s) {
transform(s.begin(), s.end(), s.begin(), tolower);
return s;
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我不明白这是如何解决调用约定问题的?transform仍然是一个c ++函数,而tolower仍然是strTolower中的一个C函数,所以这里处理这些不同的调用约定.
要使用 Visual Studio 构建 C 库,请使用 CMake 命令
set(WINDOWS_EXPORT_ALL_SYMBOLS ON)
Run Code Online (Sandbox Code Playgroud)
使我免于添加__declspec(dllexport)
或__declspec(dllimport)
在函数声明之前;只有全局变量需要显式导入/导出符号。
在 MinGW 下(阅读:MinGW 或其推荐的替代品 Mingw-w64)这不起作用。将应用程序(也用 MinGW 构建)链接到我的库失败,直到我在每个函数前面粘贴了导入/导出符号。而长答案/sf/answers/2259938271/表明相反:MinGW 下不需要导入/导出符号。这个答案对吗?那么如何摆脱对导入/导出符号的需求?
是的,我已经阅读:http://msdn.microsoft.com/en-us/library/83ythb65.aspx
但它不是我清楚.首先,__declspec(align(#))
使用它声明的每个对象(在一个结构中)以对齐的偏移量开始.那部分很清楚.该对象也是由对象所在的结构化"继承"的.但它不会改变对象的大小,是吗?确切地说,为什么sizeof()
在这段代码中:
__declspec(align(32)) struct aType {int a; int b;};
sizeof(aType);
Run Code Online (Sandbox Code Playgroud)
回来32
?
interface __declspec(uuid("F614FB00-6702-11d4-B0B7-0050BABFC904"))
ICalculator : public IUnknown
{
//...
};
Run Code Online (Sandbox Code Playgroud)
这句话扩展到了什么?如何用ANSI C++重写它?
我正在研究库的多线程实现.在该库的一个模块中,存在一些全局变量(在程序执行中经常使用).为了更安全地访问这些变量,我使用Thread-local storage(TLS)关键字声明它们__declspec(thread)
.
这是对库外部函数的调用.此函数使用具有全局变量的模块:
for(i = 0; i<n_cores; i++)
hth[i] = (HANDLE)_beginthread((void(*)(void*))MT_Interface_DimenMultiCells,0,(void*)&inputSet[i]);
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我猜每个线程都会复制库中使用的所有变量.
当我在x8内核处理器上运行程序时,完成操作所需的时间不会超过单个进程实现所需时间的1/3.
我知道不可能达到1/8的时间,但我认为至少1/6是可以达到的.
问题是:那些__declspec(线程)变量是如此糟糕表现的原因?
在此先感谢,GB
我一直在努力研究如何将一个字符串数组从c ++ dll返回到ac#应用程序,但我仍然坚持如何做到这一点或在一个非常基本的层面上找到一篇文章.
假设我有以下代码.如何修复粗体线:
extern "C" {
__declspec(dllexport) int GetANumber();
//unsure on this line:
**__declspec(dllexport) ::vector<std::string> ListDevices();**
}
extern::vector<std::string> GetStrings()
{
vector<string> seqs;
return seqs;
}
extern int GetANumber()
{
return 27;
}
Run Code Online (Sandbox Code Playgroud)
谢谢
马特
declspec ×10
c++ ×8
c ×2
dll ×2
visual-c++ ×2
alignment ×1
attributes ×1
c# ×1
cmake ×1
dllexport ×1
dllimport ×1
mingw ×1
performance ×1
pinvoke ×1
qt ×1
sizeof ×1
vector ×1
visibility ×1
windows ×1