从C++;到C在powerpc上似乎不起作用 当我从C++调用方传递复杂浮点(复合体.h)到C库时,当在32位Power PC上运行时,该值不会正确通过。当我发现这个问题时,我使用两个不同的开源软件库。我把它隔离到C++把复杂的值类型传递给纯C类型函数的边界。我写了一些简单的代码来演示它 #ifndef MMYLIB_3A8726C1_H #define MMYLIB_3A8726C1_H typedef struct aComplexStructure { float r; float i; } myComplex_t; #ifdef __cplusplus #include <complex> extern "C" { void procWithComplex(float a, std::complex<float> *pb, std::complex<float> c, float d); void procWithStruct(float a, myComplex_t *pb, myComplex_t c, float d); } #else /* __cplusplus */ #include <complex.h> void procWithComplex(float a, float complex *pb, float complex c, float d); void procWithStruct(float a, myComplex_t *pb, myComplex_t c, float d); #endif #endif /* MYLIB_3A8726C1_H */

从C++;到C在powerpc上似乎不起作用 当我从C++调用方传递复杂浮点(复合体.h)到C库时,当在32位Power PC上运行时,该值不会正确通过。当我发现这个问题时,我使用两个不同的开源软件库。我把它隔离到C++把复杂的值类型传递给纯C类型函数的边界。我写了一些简单的代码来演示它 #ifndef MMYLIB_3A8726C1_H #define MMYLIB_3A8726C1_H typedef struct aComplexStructure { float r; float i; } myComplex_t; #ifdef __cplusplus #include <complex> extern "C" { void procWithComplex(float a, std::complex<float> *pb, std::complex<float> c, float d); void procWithStruct(float a, myComplex_t *pb, myComplex_t c, float d); } #else /* __cplusplus */ #include <complex.h> void procWithComplex(float a, float complex *pb, float complex c, float d); void procWithStruct(float a, myComplex_t *pb, myComplex_t c, float d); #endif #endif /* MYLIB_3A8726C1_H */,c++,c,pass-by-value,complex-numbers,powerpc,C++,C,Pass By Value,Complex Numbers,Powerpc,但是,当我在嵌入式power pc机上运行源代码时,我得到的输出表明complex的值类型没有正确传递 a=1.2 b=(3.4,3.4) c=(5.6,5.6) d=9.876 a=1.200000 b=3.400000 + 3.400000i c=-0.000000 + 9.876000i d=0.000000 a=1.200000 b=3.400000 + 3.400000i c=5.600000 + 5.600000i d=9.876000 我检查了gdb中参数的大小,从调用和函数

但是,当我在嵌入式power pc机上运行源代码时,我得到的输出表明complex的值类型没有正确传递

a=1.2
b=(3.4,3.4)
c=(5.6,5.6)
d=9.876

a=1.200000
b=3.400000 + 3.400000i
c=-0.000000 + 9.876000i
d=0.000000

a=1.200000
b=3.400000 + 3.400000i
c=5.600000 + 5.600000i
d=9.876000
我检查了gdb中参数的大小,从调用和函数框架中,浮点、复数浮点指针、复数浮点和浮点的大小分别为4字节、4字节、8字节和4字节

<>我意识到,当我将C++的C语言替换为C,但我想知道为什么我不能把一个复杂的值类型从C++传递到C上。 我创建了另一个示例,只是这次我转储了一些程序集和寄存器值

int x = 22;
std::complex<float> y = 55 + 88I;
int z = 77;
void simpleProc(int x, complex float y, int z)
这应该是汇编代码,它保存返回地址并保存要传递到例程中的参数

x0x10000b78 <main()+824> lwz     r9,40(r31)
x0x10000b7c <main()+828> stw     r9,72(r31)
x0x10000b80 <main()+832> lwz     r9,44(r31)
x0x10000b84 <main()+836> stw     r9,76(r31)   
x0x10000b88 <main()+840> addi    r9,r31,72    
x0x10000b8c <main()+844> lwz     r3,16(r31)   
x0x10000b90 <main()+848> mr      r4,r9       
x0x10000b94 <main()+852> lwz     r5,20(r31)   
x0x10000b98 <main()+856> bl      0x10000f88 <simpleProc>  

我的Layman视图是,看起来C++正在将复杂值类型作为引用或指针类型传递?但是C把它当作一个值类型?这是power pc上的gcc的问题吗?我使用的是gcc4.7.1。我正在另一台机器上构建gcc4.9.3作为交叉编译器。一旦我从一个新的编译器获得输出,我将以任何方式更新这篇文章


在交叉编译器工作时遇到问题,但从原始问题的内存转储来看,它确实表明在power pc平台上,复杂值不是按值传递的。我把这个结构的例子放在这里是为了说明64位的值可以在32位机器上按值传递。

您的代码会导致未定义的行为。在C++单元中,函数被声明为:

extern "C" void procWithComplex(float a, std::complex<float> *pb, std::complex<float> c, float d);
这不匹配

要帮助编译器诊断此错误,应避免使用预处理器为同一函数切换不同的原型


<> P>为了避免这个错误,您需要函数原型只使用C和C++中都有效的类型。就像您在
myComplex\t
示例中所做的那样。

我们最终在开发板上使用了交叉编译器和本机编译器来创建二进制文件。显然,对于我们使用的本机编译器,C到C++边界显然没有处理复杂的数字。


所有建议的更改都尝试过,但都失败了,但它们仍然是很好的建议。这有助于确认我们的想法,这可能是一个编译器问题,使我们能够尝试使用交叉编译器。谢谢大家

这不是问题所在,但以下划线开头,后跟大写字母(
\u MYLIB\u H\u
)的名称和包含两个连续下划线的名称将保留给实现。不要尝试使用它们。你是否尝试在C代码部分中的Power PC上创建预期的复数值,并将预期值的十六进制和从C++部分输入的值的值进行倒排,以查看它们的不同之处?一个是类模板实例,另一个是内置类型,它们的参数传递约定不一定是相同的,即使二进制布局幸运地重合。我同意@ n.m。如果您希望C代码和C++代码互操作,则使用相同的类型。代码< > MyFieldTys>代码> Works:因为它是C和C++代码的相同类型。这只是我尝试运行代码时的问题(用GCC 4.7.1构建)。在32位powerpc嵌入式平台上。在GCC 4.85.5编译的X8664 64 GNU/Linux平台上,通过复杂的浮点在C++到C边界上工作。我目前没有访问其他平台的权限,因此无法验证这是否发生在power pc以外的其他平台上。我怀疑它与power pc隔离,因为这似乎是其他人以前遇到过的问题。这不是正确的解决方案。您正在调用UB,但幸运的是,您的代码随时可能爆炸。
int x = 22;
std::complex<float> y = 55 + 88I;
int z = 77;
void simpleProc(int x, complex float y, int z)
x = 22
y =  {_M_value = 55 + 88 * I} 
Looking at raw data *(int*)&y = 1113325568
z = 77
x0x10000b78 <main()+824> lwz     r9,40(r31)
x0x10000b7c <main()+828> stw     r9,72(r31)
x0x10000b80 <main()+832> lwz     r9,44(r31)
x0x10000b84 <main()+836> stw     r9,76(r31)   
x0x10000b88 <main()+840> addi    r9,r31,72    
x0x10000b8c <main()+844> lwz     r3,16(r31)   
x0x10000b90 <main()+848> mr      r4,r9       
x0x10000b94 <main()+852> lwz     r5,20(r31)   
x0x10000b98 <main()+856> bl      0x10000f88 <simpleProc>  
x0x10000f88 <simpleProc>         stwu    r1,-48(r1)  
x0x10000f8c <simpleProc+4>       mflr    r0      
x0x10000f90 <simpleProc+8>       stw     r0,52(r1)   
x0x10000f94 <simpleProc+12>      stw     r29,36(r1)  
x0x10000f98 <simpleProc+16>      stw     r30,40(r1)  
x0x10000f9c <simpleProc+20>      stw     r31,44(r1)  
x0x10000fa0 <simpleProc+24>      mr      r31,r1      
x0x10000fa4 <simpleProc+28>      stw     r3,8(r31)  
x0x10000fa8 <simpleProc+32>      stw     r5,12(r31) 
x0x10000fac <simpleProc+36>      stw     r6,16(r31)  
x0x10000fb0 <simpleProc+40>      stw     r7,20(r31)  
x0x10000fb4 <simpleProc+44>      lis     r9,4096  
x = 22
y =  1.07899982e-43 + 0 * I
z = 265134296

$r3 = 22
$r4 = 0x9ffff938
*(int*)$r4 = 1113325568
$r5 = 77

*(int*)(&y) = 77
extern "C" void procWithComplex(float a, std::complex<float> *pb, std::complex<float> c, float d);
void procWithComplex(float a, complex float * pb, complex float  c, float d)