Delphi中调用VC的DLL,并传入结构体参数,出现问题!!!!
我用VC写了个动态链接库,采用插件的方式输出接口。接口中有一个函数是这样的:int(*GetMusicInfo)(MUSIC_INFORMATION*MusicInfo,...
我用VC写了个动态链接库,采用插件的方式输出接口。
接口中有一个函数是这样的:
int (*GetMusicInfo)(MUSIC_INFORMATION *MusicInfo, int MusicInfoSize, void* ThisPort);
结构体MUSIC_INFORMATION的定义如下:
typedef struct MUSIC_INFORMATION
{
char FilePathName[512];
char Title[256];
char Artist[256];
char Album[256];
char Comment[256];
char Year[256];
char Genre[256];
char CodecName;
int LengthInMS;
int SampleRate;
int nChannels;
int BitRate;
int BitDepth;
int VBR;
} MUSIC_INFORMATION;
用VS2008编译了两个版本(一个是上述结构体1字节内存边界对齐,一个是默认对齐),全部通过,没有任何警告和错误!
然后在Delphi中定义接口,并定义上述结构体
GetMusicInfo函数定义为cdecl调用方式
结构体定义如下:
type TMusicInfo = record //后来此处加了packed
FilePathName:Array[0..512] of CHAR;
Title:Array[0..256] of CHAR;
Artist:Array[0..256] of CHAR;
Album:Array[0..256] of CHAR;
Comment:Array[0..256] of CHAR;
Year:Array[0..256] of CHAR;
Genre:Array[0..256] of CHAR;
CodecName:PChar;
LengthInMS:Integer;
SampleRate:Integer;
nChannels:Integer;
BitRate:Integer;
BitDepth:Integer;
VBR:Integer;
end;
同样,在Delphi下编译了两个版本的EXE程序,一个是1字节内存对齐,一个是默认对齐!
经过反复试用后,发现不匹配内存对齐的DLL和EXE在一起时出现堆栈错误!
匹配的放在一起时,虽然无错误,但是调用函数后,结构体里的每个成员的指针好像都前移了两个字节!
比如Title,内容本来应该是"I Love You"的,但是Delphi中调用后的内容却为"Love You",前面的两个字节没了!其他成员也是如此!
如果用VC写EXE程序来调用DLL,则不会有问题!
进过调试,GetMusicInfo函数的堆栈平衡,DLL没有任何问题!
此函数的有关参数MUSIC_INFORMATION *MusicInfo的大概代码是:
strcpy_s(MusicInfo->xxx, sizeof(MusicInfo->xxx), yyy);
再无其他操作!
请问各位高手,这是怎么回事????
如解答正确,再追分!
在Delphi中的调用代码为:
InMod.GetMusicInfo(@MyMusicInfo, sizeof(MyMusicInfo), InMod);
InMod为插件接口实例,MyMusicInfo为MUSIC_INFORMATION实例!
如何使编译字节内存对齐?
在声明结构体时,加入packed关键字,即可!或者在工程设置里,找到编译选项卡,即可看见结构体成员内存对齐选项! 展开
接口中有一个函数是这样的:
int (*GetMusicInfo)(MUSIC_INFORMATION *MusicInfo, int MusicInfoSize, void* ThisPort);
结构体MUSIC_INFORMATION的定义如下:
typedef struct MUSIC_INFORMATION
{
char FilePathName[512];
char Title[256];
char Artist[256];
char Album[256];
char Comment[256];
char Year[256];
char Genre[256];
char CodecName;
int LengthInMS;
int SampleRate;
int nChannels;
int BitRate;
int BitDepth;
int VBR;
} MUSIC_INFORMATION;
用VS2008编译了两个版本(一个是上述结构体1字节内存边界对齐,一个是默认对齐),全部通过,没有任何警告和错误!
然后在Delphi中定义接口,并定义上述结构体
GetMusicInfo函数定义为cdecl调用方式
结构体定义如下:
type TMusicInfo = record //后来此处加了packed
FilePathName:Array[0..512] of CHAR;
Title:Array[0..256] of CHAR;
Artist:Array[0..256] of CHAR;
Album:Array[0..256] of CHAR;
Comment:Array[0..256] of CHAR;
Year:Array[0..256] of CHAR;
Genre:Array[0..256] of CHAR;
CodecName:PChar;
LengthInMS:Integer;
SampleRate:Integer;
nChannels:Integer;
BitRate:Integer;
BitDepth:Integer;
VBR:Integer;
end;
同样,在Delphi下编译了两个版本的EXE程序,一个是1字节内存对齐,一个是默认对齐!
经过反复试用后,发现不匹配内存对齐的DLL和EXE在一起时出现堆栈错误!
匹配的放在一起时,虽然无错误,但是调用函数后,结构体里的每个成员的指针好像都前移了两个字节!
比如Title,内容本来应该是"I Love You"的,但是Delphi中调用后的内容却为"Love You",前面的两个字节没了!其他成员也是如此!
如果用VC写EXE程序来调用DLL,则不会有问题!
进过调试,GetMusicInfo函数的堆栈平衡,DLL没有任何问题!
此函数的有关参数MUSIC_INFORMATION *MusicInfo的大概代码是:
strcpy_s(MusicInfo->xxx, sizeof(MusicInfo->xxx), yyy);
再无其他操作!
请问各位高手,这是怎么回事????
如解答正确,再追分!
在Delphi中的调用代码为:
InMod.GetMusicInfo(@MyMusicInfo, sizeof(MyMusicInfo), InMod);
InMod为插件接口实例,MyMusicInfo为MUSIC_INFORMATION实例!
如何使编译字节内存对齐?
在声明结构体时,加入packed关键字,即可!或者在工程设置里,找到编译选项卡,即可看见结构体成员内存对齐选项! 展开
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询