DLL的文件应用?

lxl 2004-01-10 11:52:48
调用的DLL是用C编写的,其中的对方的函数说明是
GETDATA(const char* s1,char* s2)
其中S1为输入参数,S2为输出参数,
函数的输出类型为INT,如果INT=0时,则正确调用了,
我在使用时是这样调用的
说明部分:
Function Getdata(s1:pchar;s2 : pchar ):integer;cdecl; External 'VCNEW.dll';
使用部分:
var s1,s2: pchar;
begin
s1:=pchar(edit1.text);
getmem(edit1,256);
if Getdata(s1,s2)=0 then
edit2.text:=buffer;
end;

但在运行的时候报错:“access viliation as ox000725”
这是怎么回事,到底应该如何调用?
...全文
138 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxl 2004-01-11
  • 打赏
  • 举报
回复
呵呵,对不起,因为当时程序不在手上,一时写错了
Function Getdata(s1:pchar;s2 : pchar ):integer;cdecl; External 'VCNEW.dll';
使用部分:
var s1,s2: pchar;
begin
//在这时给S2空间,我写错为EDIT2了
getmem(s2,256);
S1:=pchar(edit1.text);
if Getdata(s1,s2)=0 then
edit2.text:=S2;
//就是在用到下面这一句时,出现错误提示:“access viliation as ox000725”
//所以估计是没有对GETMEM应用相应的FREEMEM,加入一句FREEMEM(S2);就OK了
end;

谢谢各位,让偶又学到了不少
结贴
aiirii 2004-01-10
  • 打赏
  • 举报
回复
s1, s2都改成 GetMem ,
用 Strcopy 拷貝 edit1.text 到 s1,

edit2.text := StrPas(s2);

如果還不行, 將cdecl改成 stdcall
ttzzj 2004-01-10
  • 打赏
  • 举报
回复
有问题给我发消息!
ttzzj 2004-01-10
  • 打赏
  • 举报
回复
顺便问一下,
getmem(edit1,256);//干吗?
edit2.text:=buffer;//buffer在哪?

ttzzj 2004-01-10
  • 打赏
  • 举报
回复
Function Getdata(s1:pchar;s2 : pchar ):integer;cdecl; External 'VCNEW.dll';
使用部分:
var s1,s2: pchar;
begin
s1:=pchar(edit1.text);
getmem(edit1,256);
///////////////////////////////////
s2的内存地址呢?
s2的长度呢?
////////////////////////////////////
if Getdata(s1,s2)=0 then
edit2.text:=buffer;
end;


给分~~~~~~hehe
delphiseabird 2004-01-10
  • 打赏
  • 举报
回复
在Delphi中调用VC++创建的动态链接库的实例
(一)实验环境
本实例的编程工具及运行环境为:Windows 98,VC++6.0,Delphi 5.0 。

(二)实验内容
1.用VC++6.0建立一个动态链接库MaxMin.DLL,该库中包含有两个函数:返回三个整数中最大整数的函数Max1( )和返回三个整数中最小整数的函数Min1( )。
2.用Delphi编写测试程序调用动态链接库MaxMin.DLL中的两个函数。

(三)实验步骤
1.用VC++6.0建立动态链接库MaxMin.DLL
第一步:启动VC++6.0,选择“File/New/MFC AppWizzard(Dll)”,工程名设为“MaxMin”,按“确定”钮后,选择“Regular DLL Using shared MFC DLL”,按“Finish”钮后,即创造了一个DLL的框架工程。
第二步:选择“File/New”,在出现的对话框中选择“C/C++ Header File”,在文件名处输入“MyDLL”,按“确定”钮,即创建了一个空的头文件“MyDLL.h”。在该文件中输入以下两行内容:
extern "C" _declspec(dllexport) int Min1(int x,int y,int z);
extern "C" _declspec(dllexport) int Max1(int x,int y,int z);
选择“File/Save”保存该文件的内容。
第三步:选择“File/New”,在出现的对话框中选择“C/C++ Source File”, 在文件名处输入“MyDLL”,按“确定”钮,即创建了一个空的源文件“MyDLL.cpp”。在该文件中输入以下内容:
#include "stdafx.h"
#include "MyDll.h"
extern "C" __declspec(dllexport) int Min1(int x,int y,int z)
{
if ((x<=y) & (x<=z)) return x;
else if ((y<=x) & (y<=z)) return y;
else return z; /*找出x,y,z中的最小整数*/
}

extern "C" __declspec(dllexport) int Max1(int x,int y,int z)
{
if ((x>=y) & (x>=z)) return x;
else if ((y>=x) & (y>=z)) return y;
else return z; /*找出x,y,z中的最大整数*/
}
选择“File/Save”保存该文件的内容。
第四步:按下运行图标“!”,即生成了MyDLL.DLL(在当前工程目录的DEBUG子目录下)。

2.用Delphi编写调用MaxMin.DLL的测试程序
调用动态链接库有两种方法,即隐式调用和显式调用。
(1)隐式调用
第一步:启动Delphi,选择“New Application”,生成一个空的应用程序,在Form的“Name”属性处输入“TestVcDLLForm”,Caption属性处输入“VC++的DLL隐式调用测试”,在Form中放入控件如表1所示(其中所有的Edit控件的“Text”属性均设为空):


最后设计的Form的屏幕效果如图1所示。选择“File/Save all”,在“Save unit1 as”对话框中将源文件名设为“main.pas”,按“保存”钮;在“Save Project1 as”对话框中将工程名设为“TestVcDLL”,按“保存”钮。
第二步:选择“File/New…”,在出现的“New Item”对话框中选择“unit”,按“OK”钮,生成一个空的源文件,在该文件中输入以下内容:
unit MaxMin;

interface
function Min1(x,y,z:Integer):Integer; stdcall;
function Max1(x,y,z:Integer):Integer; stdcall;

implementation
function Min1;external 'MaxMin.DLL' name 'Min1';
function Max1;external Max'Min.DLL' name 'Max1';
end.
选择“File/Save As…”,将上述文件存为“MaxMin.pas”。
第三步:在Main.pas文件中,在“implementation”语句后加入:
uses
MaxMin;
第四步:在Form上双击“运行”按钮对该按钮的“Click”事件编程,代码如下:
procedure TTestVcDLLForm.btnRunClick(Sender: TObject);
begin
edtMax.Text:=IntToStr(Max1(StrToInt(edtInt1.Text),
StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //调用动态链接库中的函数Max1
edtMin.Text:=IntToStr(Min1(StrToInt(edtInt1.Text),
StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //调用动态链接库中的函数Min1
end;
保存该文件。
第五步:将上述1.中VC++6所建立的动态链接库“MaxMin.DLL”拷入Delphi的当前工作目录中。
第六步:运行。

(2)显示调用
第一步:同隐式调用。只是将Form的“Caption”属性改为“VC++的DLL显式调用测试”。
第二步:选择“File/New…”,在出现的“New Item”对话框中选择“unit”,按“OK”钮,生成一个空的源文件,在该文件中输入以下内容:
unit Unit1;

interface

type
TMin1=function(x,y,z:Integer):Integer; stdcall;
TMax1=function(x,y,z:Integer):Integer; stdcall;
THandle=Integer;

implementation

end.
选择“File/Save As…”,将上述文件存为“MaxMin.pas”。
第三步:在Main.pas文件中,在“implementation”语句后加入:
uses
MaxMin;
第四步:在Form上双击“运行”按钮对该按钮的“Click”事件编程,代码如下:
procedure TTestVcDLLForm.btnRunClick(Sender: TObject);
var
Handle:THandle;
Min1:TMin1;
Max1:TMax1;
begin
Handle:=LoadLibrary('MaxMin.dll'); //将“MaxMin.dll”的文件映象映射进调用进程的地址空间
if Handle<>0 then
begin
@Min1:=GetProcAddress(Handle,'Min1'); //取得DLL中函数Min1( )的地址
@Max1:=GetProcAddress(Handle,'Max1'); //取得DLL中函数Max1( )的地址
if (@Min1<>nil) and (@Min1<>nil) then
begin
edtMin.Text:=IntToStr(Min1(StrToInt(edtInt1.Text),
StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //调用动态链接库中的函数Min1
edtMax.Text:=IntToStr(Max1(StrToInt(edtInt1.Text),
StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //调用动态链接库中的函数Max1
end else ShowMessage('调用函数“GetProcAddress”时出错!');
FreeLibrary(Handle); //从进程的地址空间中解除“MaxMin.dll”文件的映射
end;
end;
保存该文件。
第五步:将上述1.中VC++6所建立的动态链接库“MaxMin.DLL”拷入Delphi的当前工作目录中。
第六步:运行。
(这个东西仅供参考,谁让我看见分就眼红)
sixgj 2004-01-10
  • 打赏
  • 举报
回复
顶顶……
Hedonism 2004-01-10
  • 打赏
  • 举报
回复
reallike 2004-01-10
  • 打赏
  • 举报
回复
interface

function GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;

implementation

function GetProcAddress; external kernel32 name 'GetProcAddress';
reallike 2004-01-10
  • 打赏
  • 举报
回复
cooling(cooling)就这类问题,你昨天就扔下半句话给别人。不真正解决问题就少说两句!

楼顶的,使用DLL无非就这两种方法,直接导出函数名,还有传递内存地址。

interface关键字后面好好的声明原型,implementation后面导出。

在windows.pas里面有N多这么声明的的东西,好好看看吧。
deepWATERblue 2004-01-10
  • 打赏
  • 举报
回复
UP.
reallike 2004-01-10
  • 打赏
  • 举报
回复
内存地址的调用。

//声明类型
type
TGetdata = function(s1:pchar;s2 : pchar ):integer;cdecl;stdcall;

//事件内:
const
cVCNEW = 'VCNEW.dll';
var
LibHandle: THandle;
s1,s2: pchar;
Getdata: TGetdata;
begin
//得到句柄
LibHandle := LoadLibrary(cVCNEW);
//得到入口地址传递给你的对象
@Getdata := GetProcAddress(LibHandle, 'Getdata');
//使用
Getdata(s1, s2);
Showmessage(s1);
Showmessage(s2);
//释放
FreeLibrary(LibHandle);
end;
reallike 2004-01-10
  • 打赏
  • 举报
回复
如果是导出函数调用
//interface关键字下:

interface
Function Getdata(s1:pchar;s2 : pchar ):integer;cdecl;stdcall;

//implementation关键字下

implementation

function Getdata; external 'VCNEW.dll' name 'Getdata';
reallike 2004-01-10
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/topic/2649/2649153.xml?temp=.6675379

昨天我回答的问题。你在显式调用的时候有错误。
ttzzj 2004-01-10
  • 打赏
  • 举报
回复
老大们,不要用那种眼光看只有两个三角的,
我刚昨天注册的帐号,,,,
专家分也才两百分
ttzzj 2004-01-10
  • 打赏
  • 举报
回复
To : cooling(cooling):
返回值就不需要地址了吗?就可以不分配内存了吗?
这可是传址的!!!没听楼主说用
CCC
C
C
CCC
写的动态连接库吗,没看见那C函数的定义吗?
cooling 2004-01-10
  • 打赏
  • 举报
回复
to ttzzj(标识符)

Function Getdata(s1:pchar;s2 : pchar ):integer;cdecl; External 'VCNEW.dll';
使用部分:
var s1,s2: pchar;
begin
s1:=pchar(edit1.text);
getmem(edit1,256);
///////////////////////////////////
s2的内存地址呢?
s2的长度呢?
////////////////////////////////////
if Getdata(s1,s2)=0 then
edit2.text:=buffer;
end;


给分~~~~~~hehe



(讨论)*************************

这里s2不是返回值吗?

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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