我在cpp文件中看到ts = datetime.datetime.now()
cursor.prepare("INSERT INTO python_tstamps VALUES(:t_val)")
cursor.setinputsizes(t_val=cx_Oracle.TIMESTAMP)
cursor.execute(None, {'t_val':ts})
db.commit()
包含了几个函数的定义。
从https://isocpp.org/wiki/faq/mixing-c-and-cpp开始,我想在cpp文件中使用external "C" {...}
的目的是使附带的C ++函数可用于C程序。
链接中的示例显示extern "C"
仅包含C ++函数的声明,而不是它们的定义
只需声明C ++函数extern“C”(在您的C ++代码中)并调用 它(来自您的C或C ++代码)。例如:
extern "C"
我在开头提到的cpp文件看起来像:
// C++ code:
extern "C" void f(int);
void f(int i)
{
// ...
}
应该{{1}}包含C ++函数的声明或定义吗? 如果是这样,为什么?
答案 0 :(得分:15)
它应该将声明括在头文件中,并且只要使用c ++编译器编译转换单元就应该包含定义,并且只要在那里看不到声明。
在c ++代码中做两件事都没有错。
如果c编译器用于编译函数定义,则没有必要(或者我应该更好地说语法错误,请参阅下面的注释)。
extern "C" {}
范围控制普通c符号链接用于内部的所有内容。否则c++ name mangling将被应用。
注意:
由于extern "C" {}
这不是有效的c语法,为了使其与c编译器一起使用,您需要在#ifdef
中使用它:
<强> MyHeader.h
强>
#ifdef __cplusplus
extern "C" {
#endif
// ... c style function name declarations
void foo(int i);
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {}
范围实际上是双重的:如果使用c编译器编译上述内容,则会将其显示为普通的c函数声明。如果使用c ++编译器编译,则应用extern
关键字,并且将禁止c ++名称修改。
关于定义,该函数可以使用其定义中的任何c ++特性:
extern "C" {
void foo(int x) {
std::vector v(x);
// ... blah, more c++ stuff
}
}
请注意,此处未包含声明。这可以用作一种技术,当您想要覆盖从weak linkage库中公开的函数时,它尤其有用。
如果包含MyHeader.h
,则extern "C" {}
范围可以省略。
如果在c ++编译器中看到上述声明,则再次禁止c ++名称修改,并且链接器将使用普通c函数符号名称解析对foo()
的任何调用引用:
#include "MyHeader.h"
class MyClass {
public:
void bar(int y) {
// Use foo() as plain c function:
foo(y);
}
};
foo()
函数实现是使用c编译器创建的目标文件(或归档文件)提供的。
答案 1 :(得分:7)
[dcl.link] / 5:
除了具有C ++链接的函数,没有函数声明 链接规范不应在第一个链接之前 该功能的规范。可以在没有a的情况下声明函数 已经明确的链接规范之后的链接规范 可见;前面声明中明确指定的链接是 不受这种功能声明的影响。
就功能的语言链接而言,两个版本都很好。重要的是,函数的第一个声明必须有extern "C"
。
答案 2 :(得分:3)
最好包括两者。
当我们在C ++中链接C代码时,确保符号没有被破坏。我们使用extern&#34; C&#34;块。
每当将某些代码放在extern“C”块中时,C ++编译器就会确保函数名称是无符号的,即编译器生成一个二进制文件,其名称不变,就像C编译器一样。
Mangling由于C ++支持函数重载,所以基本上可以有多个具有相同名称的函数。因此,在生成目标代码时要区分不同的函数 - 它通过添加有关参数的信息来更改名称。向函数名添加附加信息的技术称为Name Mangling。
由于C不支持函数重载。所以我们使用extern&#39; C&#39;在C ++中链接C代码时阻塞。
答案 3 :(得分:1)
您应该包含声明和定义。 &#34; C&#34;和&#34; C ++&#34;函数以不同的名称导出。为了产生正确的&#34; C&#34; cpp中需要对象文件matcher.matches()
中的外部名称,否则将使用C++ name mangling导出函数。您还需要将那些extern "C"
和相应的extern "C" {
括在头文件中的}
和#ifdef __cplusplus
中,这将被C项目#included以避免C编译错误
答案 4 :(得分:-2)
在same document中,它显示了一个代码示例,该示例在声明中有For i = ActiveChart.SeriesCollection.Count To 1 Step -1
If ActiveChart.Legend(i)= "Test: *" Then
ActiveChart.Legend(i) **what I think needs to be modified**
End If
Next i
,但在定义中没有。
如果您的定义&#34;看到&#34;声明(即声明在翻译单元中的定义之前),您不需要extern "C"
定义。但它不会受到伤害 - 编译器会默默地忽略它。
这是FAQ中给出的代码示例:
extern "C"
如果您出于任何原因决定不在定义之前加入声明,则必须提供// This is C++ code
// Declare f(int,char,float) using extern "C":
extern "C" void f(int i, char c, float x);
// ...
// Define f(int,char,float) in some C++ module:
void f(int i, char c, float x)
{
// ...
}
修饰符:
extern "C"
然而,这违背了C和C ++的大多数风格指南。