C++Builder 程序员博客
27 Aug
急着交啊.
c++中声明如下:
typedef struct T{
float Re;
float Im;
}TComplex;
__declspec(dllexport) void _stdcall ABCC(TComplex Source[],TComplex Dest[],int Count);
delphi中声明和调用如下:
procedure ABCC(var Source: array of TComplex; var Dest:array of TComplex;var Count: integer);stdcall;external 'DLL.dll';
var
t1,t2:array of TComplex;
i:integer;
t:single;
begin
GetMem(t1,sizeof(TComplex)*2);
t:=1.11;
for i:=0 to 1 do
begin
t1[i].Re:=t;
t:=t+1.11;
t1[i].Im:=t;
t:=t+1.11;
end;
GetMem(t2,sizeof(TComplex)*2);
i:=2;
ABCC(t1,t2,i);
}
发现进入dll后,第二个参数和第三个参数的值传不进去,只要使用到第二个参数就读写错.
第一个参数正常,晕死,急着交啊.
DLL的参数不能使用class相关的东西.
delphi 中TComplex声明如下:
TComplex = packed record
Re: float;
Im: float;
end;
不好意思 看错了
procedure ABCC(var Source: of TComplex; var Dest:TComplex;Count:integer);stdcall;external 'DLL.dll';
回2楼,用delphi生成的dll,可以这样调用,我现在是把delphi代码改为c++的
多写了一个of
procedure ABCC(var Source:TComplex; var Dest:TComplex;Count:integer);stdcall;external 'DLL.dll';
不好意思复制错了,这三个参数,有两个是动态结构数组;
var Source: array of TComplex; var Dest:array of TComplex;var Count: integer
__declspec(dllexport) void _stdcall ABCC(TComplex Source[],TComplex Dest[],int Count);
前两个参数只TComplex* ,是指向TComplex 类型的指针,
你用var Source:TComplex是可以的
,你也可以传元素的指针进去用source:^TComplex类型的参数.
var Source:TComplex是可以,但要在DLL中访问数组其他元素怎么办?
你传入一个数组的第一个元素,其实传递的也还是一个指针.
dll中自然可以正常访问.
这样改不行,现在是要求我写C的dll,用delphi调,delphi这边的程序不变了
谢!
1.C++导出函数给delphi用要加extern "C"
2.delphi的record传参数入栈时会多放一个结构长
3.delphi的var Count传的是地址
所以你的C++要这样写(我测试一下,通过)
extern "C" __declspec(dllexport) void __stdcall ABCC(TComplex Source[],int,TComplex Dest[],int,int &Count)
14楼的朋友,好像不行啊,能在c++中读出第二个参数结构数组的值吗?
验证后还是不对
忘了结构定义了:
typedef struct T{
double Re;
double Im;
}TComplex; //delphi没有float
我的delphi的定义:
type TComplex=packed record
Re:real;
Im:real;
end;
procedure ABCC(Source: array of TComplex; Dest:array of TComplex; var Count: integer);stdcall;external 'bcbd.dll';
完整的测试程序:
//————————————————————————— #include <windows.h> //————————————————————————— // Important note about DLL memory management when your DLL uses the // static version of the RunTime Library: // // If your DLL exports any functions that pass String objects (or structs/ // classes containing nested Strings) as parameter or function results, // you will need to add the library MEMMGR.LIB to both the DLL project and // any other projects that use the DLL. You will also need to use MEMMGR.LIB // if any other projects which use the DLL will be performing new or delete // operations on any non-TObject-derived classes which are exported from the // DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling // EXE’s to use the BORLNDMM.DLL as their memory manager. In these cases, // the file BORLNDMM.DLL should be deployed along with your DLL. // // To avoid using BORLNDMM.DLL, pass string information using "char *" or // ShortString parameters. // // If your DLL uses the dynamic version of the RTL, you do not need to // explicitly add MEMMGR.LIB as this will be done implicitly for you //————————————————————————— #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } typedef struct T{ double Re; double Im; }TComplex; extern "C" __declspec(dllexport) void __stdcall ABCC(TComplex Source[],int,TComplex Dest[],int,int &Count); extern "C" __declspec(dllexport) void __stdcall ABCC(TComplex Source[],int,TComplex Dest[],int,int &Count) { for (int i=0;i<Count;i++) { Dest[i].Re= Source[i].Re; Dest[i].Im= Source[i].Im; } } //—————————————————————————
unit d1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} type TComplex=packed record Re:real; Im:real; end; procedure ABCC(Source: array of TComplex; Dest:array of TComplex; var Count: integer);stdcall;external ‘bcbd.dll‘; procedure TForm1.Button1Click(Sender: TObject); var t1,t2:array of TComplex; ct:integer; begin ShowMessage(inttostr(sizeof(TComplex))); GetMem(t1,sizeof(TComplex)*2); GetMem(t2,sizeof(TComplex)*2); t1[0].re:=111; t1[0].Im:=222; t1[1].re:=333; t1[1].Im:=444; t2[0].re:=555; t2[0].Im:=666; t2[1].re:=777; t2[1].Im:=888; ct:=2; ABCC(t1,t2,ct); ShowMessage(Format(‘%f %f %f %f‘,[t2[0].re,t2[0].im,t2[1].re,t2[1].im])); end; end.
非常感谢keiy和akirya ,刚才打电话来说,这个函数用DELPHI自己调,不用我弄了,把我气晕死了,弄这个东西好几天了,不眠不休,我明天结贴给分,今天没有时间了,还要赶,命苦!
++