我在 Windows 上遇到了 CMake 生成的 DLL 文件的令人困惑的问题。在我的库中,我使用 Curiously Recurring Template Pattern 为某些类提供唯一的 ID 号:
// da/Attribute.h:
#ifndef DA_ATTRIBUTE_H
#define DA_ATTRIBUTE_H
namespace da {
typedef unsigned int AttributeId;
class AttributeBase {
public:
virtual AttributeId getTypeId() const=0;
protected:
/** Static ID counter. Every class that derives da::AttributeBase is
assigned an increment of this counter as its type ID number */
static AttributeId sNextId;
};
template <class Derived>
class Attribute : public AttributeBase {
private:
static AttributeId msTypeId;
public:
Attribute() {
if (msTypeId == 0) {
msTypeId = ++sNextId;
}
}
virtual ~Attribute() {
}
/** For static contexts */
static AttributeId typeId() {
if (msTypeId == 0) {
msTypeId = ++sNextId;
}
return msTypeId;
}
AttributeId getTypeId() const {
return typeId();
}
};
template <class Derived> AttributeId Attribute<Derived>::msTypeId = 0;
}
#endif
问题是,当我将 DLL 链接到可执行项目时,不同的 ID 方法似乎有些不一致。例如:
// Foo.h
struct Foo : public da::Attribute<Foo> {
Foo() { }
};
...
// main.cpp
Foo *foo = new Foo;
Foo->getTypeId() == 1 // True
Foo::typeId() == 1 // Should be true, but isn't. Foo::typeId() == 2
运行 GDB,在 Foo::getTypeID() 中中断,我发现“msTypeId”和“Foo::msTypeId”具有不同的内存地址。到底是怎么回事。 p>
不过,只有在 DLL 中定义了 Foo 时才会发生这种情况。 (显然只有在 Windows 7 中——我的 Debian 构建中没有这个问题)如果我在 main.cpp 中创建派生类,或者如果我只是将库中的所有代码编译到可执行文件中,则跳过完全是 DLL 步骤,它没有问题。
一切都是使用 MSYS 和 MinGW 编译的,在 Windows 7 家庭高级版上使用 GCC 4.7。
这是库的 CMakeLists.txt,以防我在上面搞砸了:
cmake_minimum_required(VERSION 2.6)
project(foo)
add_definitions(-std=c++0x)
set(CMAKE_BUILD_TYPE Debug)
set(sources
Foo.cpp
)
add_library(foo SHARED ${sources})
最佳答案
您必须从共享库中导出类型。这是使用 __declspec(dllexport) and __declspec(dllimport) 完成的装饰器。阅读 MSDN 文档;它相当复杂。
由于头文件在构建库时需要有__declspec(dllexport),在编译使用它的代码时需要有__declspec(dllimport),所以通常定义一个符号,通常称为 LIBRARYNAME_EXPORT 并根据是否定义了 LIBRARYNAME_EXPORTS #ifdefs。
CMake 在构建(共享)库时自动定义 target_EXPORTS。可以通过设置 DEFINE_SYMBOL 目标属性来覆盖它。
Unix 选择不同的路径,默认情况下导出和导入共享库中的所有符号(静态和显式隐藏的符号除外)。这会导致一些性能损失,因为需要解析更多符号,但它更易于使用(无需更改即可从静态库切换到共享库)并且更加灵活(即您可以覆盖共享库中的符号,这你不能在 Windows 中做)。
关于c++ - CMake 生成的 DLL 和 Curiously Recurring 模板 (C++) 的不正确行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13009497/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数