当我将复杂的 float(complex.h) 从 C++ 调用程序传递到 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源文件如下
#include <stdio.h>
#include "myLib.h"
void procWithComplex(float a, complex float * pb, complex float c, float d)
{
printf("a=%f\n", a);
printf("b=%f + %fi\n", creal(*pb), cimag(*pb));
printf("c=%f + %fi\n", creal(c), cimag(c));
printf("d=%f\n", d);
}
void procWithStruct(float a, myComplex_t* pb, myComplex_t c, float d)
{
printf("a=%f\n", a);
printf("b=%f + %fi\n", pb->r, pb->i);
printf("c=%f + %fi\n", c.r, c.i);
printf("d=%f\n", d);
}
调用C++程序如下
#include <iostream>
#include "myLib.h"
int main()
{
float a = 1.2;
std::complex<float> b = 3.4 + 3.4I;
std::complex<float> c = 5.6 + 5.6I;
float d = 9.876;
myComplex_t b_s, c_s;
b_s.r = b.real();
b_s.i = b.imag();
c_s.r = c.real();
c_s.i = c.imag();
std::cout << "a=" << a << std::endl;
std::cout << "b=" << b << std::endl;
std::cout << "c=" << c << std::endl;
std::cout << "d=" << d << std::endl << std::endl;
// c is a 64 bit structure being passed by value.
// on my 32 bit embedded powerpc platform, it is being
// passed by reference, but the underlying C library is
// reading it by value.
procWithComplex(a, &b, c, d);
std::cout << std::endl;
// This is only here to demonstrate that a 64 bit value field
// does pass through the C++ to C boundry
procWithStruct(a, &b_s, c_s, d);
return 0;
}
通常我希望输出是
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=5.600000 + 5.600000i
d=9.876000
a=1.200000
b=3.400000 + 3.400000i
c=5.600000 + 5.600000i
d=9.876000
但是当我在嵌入式 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 和调用帧和函数帧中检查了参数的大小,对于 float 、复数 float 指针、复数 float 和 float ,大小分别为 4 字节、4 字节、8 字节和 4 字节。
我意识到我可以将复杂值参数更改为指针,或者在跨越 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)
在传入参数的调用之前。
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
外行人的看法是 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);
但是函数体是:
void procWithComplex(float a, complex float * pb, complex float c, float d)
不匹配。
为了帮助编译器诊断此错误,您应该避免使用预处理器为同一函数切换不同的原型(prototype)。
为避免此错误,您需要让函数原型(prototype)仅使用在 C 和 C++ 中均有效的类型。正如您在 myComplex_t 示例中所做的那样。
关于c++ - 按值从 C++ 传递到 C 的复数似乎在 powerpc 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36204706/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有这样的哈希trial_hash={"key1"=>1000,"key2"=>34,"key3"=>500,"key4"=>500,"key5"=>500,"key6"=>500}我按值降序排列:my_hash=trial_hash.sort_by{|k,v|v}.reverse我现在是这样理解的:[["key1",1000],["key4",500],["key5",500],["key6",500],["key3",500],["key2",34]]但我希望当值相同时按键的升序排序。我该怎么做?例如:上面的散列将以这种方式排序:[["key1",1000],["key3",500
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp
我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam