关于C++命名约定的几个问题

关于C++命名约定的几个问题,c++,winapi,dll,naming,extern,C++,Winapi,Dll,Naming,Extern,我试图为win32、mac os、linux、iOs等平台创建一个抽象层。 我希望这是动态链接。在不支持动态库的平台上,这不应该是一个问题,因为从我所看到的情况来看,可以编译为动态库的所有内容都可以编译为静态库,并且对代码的影响最小 现在,要说到这一点: 我创建了一个名为IThread的接口和一个名为CThread的类。我使用一个名为CreateThread的函数,该函数是用extern C定义的,可以导出它并在库外部调用它。这里的问题是,例如在win32中已经有一个名为CreateThread

我试图为win32、mac os、linux、iOs等平台创建一个抽象层。 我希望这是动态链接。在不支持动态库的平台上,这不应该是一个问题,因为从我所看到的情况来看,可以编译为动态库的所有内容都可以编译为静态库,并且对代码的影响最小

现在,要说到这一点:

我创建了一个名为IThread的接口和一个名为CThread的类。我使用一个名为CreateThread的函数,该函数是用extern C定义的,可以导出它并在库外部调用它。这里的问题是,例如在win32中已经有一个名为CreateThread的函数,因此我得到一个链接器错误。我理解这个错误以及它出现的原因,但我不确定有什么好方法可以避免这个错误。我真的不喜欢像qt使用CreateQtThread那样使用奇怪的命名。 我的另一个想法是创建一个线程管理器/工厂来创建CThread的实例,但我不确定这是否是一个好主意

你们怎么看?我这样问是因为我不想匆忙处理像这样的重要组织问题

多谢各位

我使用一个名为CreateThread的函数,该函数是用extern C定义的,可以导出它并在库外部调用它

这很糟糕。我不能谈论其他平台,但在Windows上,完全可以输出C++函数。它们只是被弄坏了,你会得到一些理智的检查,以防有人更改声明。事实上,这是导出C++函数的唯一正确方法。如果将其声明为extern C,则不会得到任何名称空间,也不会重载,如果函数中出现异常,则使用/EHsc编译的人将遇到麻烦

extern "C" _declspec(export) int _cdecl CreateThread(...
首选解决方案:不要将它们声明为extern C,而是将它们放在命名空间中

唯一的另一个解决方案是:猜猜为什么所有的C库都会在函数前面加上_lib_prefix_函数

我使用一个名为CreateThread的函数,该函数是用extern C定义的,可以导出它并在库外部调用它

这很糟糕。我不能谈论其他平台,但在Windows上,完全可以输出C++函数。它们只是被弄坏了,你会得到一些理智的检查,以防有人更改声明。事实上,这是导出C++函数的唯一正确方法。如果将其声明为extern C,则不会得到任何名称空间,也不会重载,如果函数中出现异常,则使用/EHsc编译的人将遇到麻烦

extern "C" _declspec(export) int _cdecl CreateThread(...
首选解决方案:不要将它们声明为extern C,而是将它们放在命名空间中


唯一的另一个解决方案:猜猜为什么所有的C库都在函数前面加上了前缀…

我认为你决定使用extern C是正确的,因为它允许从其他语言访问,编译器等,但这样做意味着你不能使用名称空间,所以你只需在你的函数前面加上前缀,以识别它们来自你的库,如果你愿意的话,这是一个穷人的名称空间


如果您想使用extern C,这是您必须做出的妥协。

在我看来,您使用extern C的决定是合理的,因为它允许从其他语言、编译器等进行访问。但这样做意味着您不能使用名称空间,因此您只需在函数前面加上一些前缀,以识别它们是否来自您的库,一个穷人的名字空间,如果你愿意的话


如果你想使用extern C,这是你必须做出的妥协。

好吧,我不知道你是否会喜欢这个,因为我知道与我一起工作的C开发人员发现它不美观。但是,它非常简单,可以防止像这样的碰撞。中或多或少地提到了它们的_lib_prefix_函数注释


所以,每当我使用C代码时,我基本上都使用下划线来“命名”我的函数。假设您的名称空间是MegaAbstraction,那么像CreateThread这样的东西就变成了MegaAbstraction\u CreateThread。简单的豌豆。并且没有冲突,除非其他人有一个名为MegaAbstraction的名称空间,在这种情况下,我建议找到一个其他人不太可能使用的名称空间

嗯,我不知道你是否会喜欢这个,因为我知道与我一起工作的C开发人员发现它不美观。但是,它非常简单,可以防止像这样的碰撞。中或多或少地提到了它们的_lib_prefix_函数注释


所以,每当我使用C代码时,我基本上都使用下划线来“命名”我的函数。假设您的名称空间是MegaAbstraction,那么像CreateThread这样的东西就变成了MegaAbstraction\u CreateThread。简单的豌豆。并且没有冲突,除非其他人有一个名为MegaAbstraction的名称空间,在这种情况下,我建议找到一个其他人不太可能使用的名称空间

您的CreateThread是否使用stdcall调用约定(又称WINAPI)?如果使用cdecl调用约定,它应该导出fu nction名称为_CreateThread,并避免与Win32 CreateThread函数的链接冲突

extern "C" _declspec(export) int _cdecl CreateThread(...

CreateThread是否使用stdcall调用约定(又称WINAPI)?如果使用cdecl调用约定,它应该将函数名导出为_CreateThread,并避免与Win32 CreateThread函数的链接冲突

extern "C" _declspec(export) int _cdecl CreateThread(...


Qt中没有CreateQtThread函数,甚至没有类似的函数。有一个QThread类,它有构造函数。如果需要,您可以将所有内容放在命名空间中。

Qt中没有CreateQtThread函数,甚至没有类似的函数。有一个QThread类,它有构造函数。如果需要,您可以将所有内容放在名称空间中。

您的问题是什么?你理解错误,不想重命名你的函数,所以你想知道我们对此的看法吗?是的,如果可能的话,我想让一些有更多经验的人对此发表看法。谢谢。你想让你的抽象层只用于C++或者其他语言,比如C?你想从给定的C++编译器中使用它,如果需要修改编译器,或者重新编译OYU,需要编译一次,那么C++是否需要编译,一旦与每个C++编译器一起工作?你的问题是什么?你理解错误,不想重命名你的函数,所以你想知道我们对此的看法吗?是的,如果可能的话,我想让一些有更多经验的人对此发表看法。谢谢。你想让你的抽象层只用于C++或者其他语言,比如C?如果你需要改变编译器,或者在你和每个C++编译器都工作的时候,你需要重新编译你的抽象层吗?我使用Extn C有一个很好的理由。如果我用Visual Studio 2010编译一个DLL,那么我就可以在Visual Studio 2008中使用DLL而不必重新编译整个C++。事情实际上,我可以给某人DLL和必要的包含文件接口,这个人可以使用DLL编译一个项目,因为没有实际的源文件,函数的名称不会被破坏。@Sanctus:我认为你的理解是错误的。好吧,在过去的10年里,这种混乱的模式没有改变。我不确定它在不同版本的visual studio之间是否会改变,但在不同的编译器(如gcc)上是不同的。这里有一个表显示:@ybungalowbill还有其他编译器,甚至其他语言:事实上,名称混乱在visual studio的编译器版本中并不稳定。我使用extern C有一个很好的理由。如果我使用visual studio 2010编译DLL,那么我可以在visual studio 2008中使用该DLL,而不必重新编译整件事。实际上,我可以给某人DLL和必要的包含文件接口,这个人可以使用DLL编译一个项目,因为没有实际的源文件,函数的名称不会被破坏。@Sanctus:我认为你的理解是错误的。好吧,在过去的10年里,这种混乱的模式没有改变。我不确定它在不同版本的visual studio之间是否会改变,但在不同的编译器(如gcc)上是不同的。这里有一个表显示:@ybungalowbill还有其他编译器,甚至其他语言bungalobill:事实上,名称mangling在visual studio的编译器版本中并不稳定。我的+1,我认为这是简单而优雅的。我认为学究式地坚持使用相同的函数名没有任何意义,例如:1。只要函数名是有意义的,就无所谓了。2.在一个实际的项目中,有100&1000件事情需要为一个函数命名一个特定的名称而烦恼:谢谢,在这两点上完全同意你。而且,你知道,可怕的是,我觉得我的同事们不喜欢我的命名惯例,他们担心。。。他们需要多打多少封信:我的意思是,在这些超长的描述性名称还没流行之前,我就已经用过了,虽然我把自己的名字缩减了一点,但我的意思是。。。对他们来说,如果你在看他们的代码,那么kfifl的意思对你来说应该是显而易见的。如果你不能区分kfifs和kfifc以及kfifj的意思,那么这是你的问题,而不是他们的问题。耸耸肩。我会留下来。我不愿意和这样的人一起工作。我相信一个好的来源是一个简单明了的来源,可以让下一个从事这项工作的人理解。编写极客代码是一场维护噩梦,除了作者之外,没有人知道这一点。哎呀!我的+1,我认为这是简单和优雅的。我认为学究式地坚持使用相同的函数名没有任何意义,例如:1。只要函数名是有意义的,就无所谓了。2.在一个实际的项目中,有100&1000件事情需要为一个函数命名一个特定的名称而烦恼:谢谢,在这两点上完全同意你。你知道吗,可怕的是我觉得我工作的人
我不喜欢我的命名规则我担心。。。他们需要多打多少封信:我的意思是,在这些超长的描述性名称还没流行之前,我就已经用过了,虽然我把自己的名字缩减了一点,但我的意思是。。。对他们来说,如果你在看他们的代码,那么kfifl的意思对你来说应该是显而易见的。如果你不能区分kfifs和kfifc以及kfifj的意思,那么这是你的问题,而不是他们的问题。耸耸肩。我会留下来。我不愿意和这样的人一起工作。我相信一个好的来源是一个简单明了的来源,可以让下一个从事这项工作的人理解。编写极客代码是一场维护噩梦,除了作者之外,没有人知道这一点。哎呀!