在Delphi中调用C编写的DLL

viper520 2008-05-14 08:59:04
我在C中写了一个DLL
__declspec(dllexport) int GetMD5(unsigned char *pBuf, int BufLen, char *OutMD5Str, int OutBufSize)
{
........
if(OutBufSize<32) return 0;
memset(OutMD5Str, 0, OutBufSize);
........
for(i=0;i<32;i++)
OutMD5Str[i] = MD5[i];
OutMD5Str[32] = '\0';
return 1;
}
编译后可以看到该DLL中有一个接口是"GetMD5"
然后我在Delphi中调用
type
TMD5Func = function(Buffer:PChar; BufLen:Integer; var MD5String:PChar; Size:Integer):Integer;cdecl;

......
var OutMD5:PChar;
MD5 := TMD5Func(ProcAddr);
MD5(PChar(Edit1.Text), Edit1.GetTextLen, OutMD5, 32);

为什么一调用就会出错????????


...全文
107 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
viper520 2008-05-17
  • 打赏
  • 举报
回复
好了,我解决了!
在delphi中要定义成数组才可以!
我的代码如下

procedure TForm1.Button1Click(Sender: TObject);
type
TTestFunc = function(var Buffer:array of char; Size:Integer):integer;cdecl;
var
DLLHandle: THandle;
RetVal, i: Integer;
ProcAddr: TFarProc;
Test: TTestFunc;
Buffer: array[0..128] of char;
strtxt: string[128];
begin
DLLHandle := loadlibrary(pchar('1.dll'));
ProcAddr := getprocaddress(dllhandle, 'TestDLL');
Test := TTestFunc(ProcAddr);
RetVal := Test(Buffer, 128);
for i:=0 to 128 do
begin
if buffer[i]=#0 then break;
strtxt[i+1] := buffer[i];
end;
Memo1.Lines.Add(strtxt);
end;

成功返回 This is a test dll!


viper520 2008-05-16
  • 打赏
  • 举报
回复
我已经将test.dll文件改名为1.dll,并且loadlibrary和getprocaddress均正常!
viper520 2008-05-16
  • 打赏
  • 举报
回复
我用VC建了一个空DLL工程,向里面添加了一个Test.c文件
内容如下
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

__declspec(dllexport) int TestDLL(char *Buffer, int Size)
{
if(Size<32) return 0;
memset(Buffer, 0, Size);
sprintf(Buffer, "This is a test dll!");
return 1;
}
编译生成 test.dll
然后在Delphi中调用
procedure TForm1.Button1Click(Sender: TObject);
type
TTestFunc = function(var Buffer:PChar; Size:Integer):integer;stdcall;//cdecl也用过了
var
DLLHandle: THandle;
RetVal: Integer;
ProcAddr: TFarProc;
Test: TTestFunc;
Buffer: PChar;
begin
DLLHandle := loadlibrary(pchar('1.dll'));
ProcAddr := getprocaddress(dllhandle, 'TestDLL');
MD5 := TMD5Func(ProcAddr);
GetMem(Buffer, 256);
RetVal := Test(Buffer, 256);
Memo1.Lines.Add(String(Buffer));
end;
结果还是错误!跟我上面遇到的错误是一样的!
是不是我的Delphi有问题?还是我的VC编译器有问题?
viper520 2008-05-16
  • 打赏
  • 举报
回复
char MD5[128];//用来保存一段数据的MD5值串,是个字符串
C代码应该没问题吧,我在VC里面是可以调用这个DLL的!
派克鼠 2008-05-16
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

__declspec __stdcall (dllexport) int TestDLL(char *Buffer, int Size)
{
if(Size <32) return 0;
memset(Buffer, 0, Size);
sprintf(Buffer, "This is a test dll!");
return 1;
}
blazingfire 2008-05-15
  • 打赏
  • 举报
回复
可能是C++的代码的问题吧
__declspec(dllexport) int GetMD5(unsigned char *pBuf, int BufLen, char *OutMD5Str, int OutBufSize)
{
........
if(OutBufSize <32) return 0;
memset(OutMD5Str, 0, OutBufSize);
........
for(i=0;i <32;i++)
OutMD5Str[i] = MD5[i];//MD5是不是没有分配空间?他是什么东西呀?
OutMD5Str[32] = '\0';
return 1;
}
blazingfire 2008-05-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 akirya 的回复:]
你知道得分配33个字节.
刚才打的有些问题
:D
[/Quote]
Yes!
  • 打赏
  • 举报
回复
分配的再长一些

var OutMD5:PChar;
MD5 := TMD5Func(ProcAddr);
GetMem(OutMD5, 64);
try
MD5(PChar(Edit1.Text), Edit1.GetTextLen, OutMD5, 64);
finally
FreeMem(OutMD5);
end;

viper520 2008-05-15
  • 打赏
  • 举报
回复
GetMem(OutMD5, 33); 了但是还会出错,貌似像堆栈不平衡了!

我还有一个接口是
__declspec(dllexport) unsigned long _GetCheckSum(unsigned char *Buf, int Size)
{
...
for(i=0;i<Size;i++)
CheckSum+=Buf[i];
return CheckSum;
}
在Delphi中调用就正常!

貌似只要参数涉及到字符串,并且那个字符串要返回的都会出现问题!
各位大哥帮帮小弟呀~~
  • 打赏
  • 举报
回复
你知道得分配33个字节.
刚才打的有些问题
:D
  • 打赏
  • 举报
回复
OutMD5Str[32] = '\0';看这里



明显分配的短了,多一个字节.
viper520 2008-05-14
  • 打赏
  • 举报
回复
我用了
var OutMD5:PChar;
MD5 := TMD5Func(ProcAddr);
GetMem(OutMD5, 32);
try
MD5(PChar(Edit1.Text), Edit1.GetTextLen, OutMD5, 32);
finally
FreeMem(OutMD5);
end;

但是还是提示错误,错误内容大概中文意思是指定内存不可读写!
gyk120 2008-05-14
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
var arr:array of Char;
begin
setlength(arr,10);//申请内存
setlength(arr,0);//这里申请的内存被自动释放了
arr:=nil;//释放arr
end
blazingfire 2008-05-14
  • 打赏
  • 举报
回复
var OutMD5:PChar;
MD5 := TMD5Func(ProcAddr);
GetMem(OutMD5, 32);
try
MD5(PChar(Edit1.Text), Edit1.GetTextLen, OutMD5, 32);
finally
FreeMem(OutMD5);
end;

viper520 2008-05-14
  • 打赏
  • 举报
回复
说的具体一点,应该怎么做??
谢谢~
僵哥 2008-05-14
  • 打赏
  • 举报
回复
OutMD5需要申请内存。

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧