当前位置:主页>销售管理软件> 列表

在VC中调用一个DLL(DELPHI写的)一个函数(很难的 找用友erp软件

财务软件版1楼: 问题:
在VC中调用一个DLL(DELPHI写的)一个函数,并传入参数,由DLL 生成一个句柄HANDLE返回给VC,下次VC调用这个DLL中的另一个函数时传入这个HANDLE,在DLL中如何根据这个传入的句柄得到上次VC传入的那些参数值?

1.用内存映射文件方式吗?
function init(const pParam:PDgramParam):THandle;stdcall;
begin
Result:=0;
hFile:= CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,
0,
SizeOf(TDgramParam),
MEM_FILENAME);
if hFile = INVALID_HANDLE_VALUE then Exit;

DgramParam:= MapViewOfFile(hFile,
File_MAP_WRITE,
0,
0,
0);
if DgramParam =nil then Exit;
Move(pParam,DgramParam,sizeof(TDgramParam));
Result:=hFile;
end;

function GetInitParams(hDgram:thandle):integer;stdcall
begin
Result:=-1;
if hDgram>0 then
[red]DgramParam [/red]:= MapViewOfFile(hDgram, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if DgramParam<>nil then
Result:=DgramParam.param1;
end;
说明:
我在DELPHI中测试,调用DLL中上面两个函数,首先调用init函数,并保存其返回的HANDLE,然后调用DLL中的另一个函数GetInitParams并传入上次返回的HANDLE.但[red][b]DgramParam[/b][/red] 始终为NIL,不知为何.
不知还有其他解决方案没有.

2楼: 顶......... 如个人记账软件

3楼: i不太明白,学习

4楼: 上次传入的在DLL里面保留啊,或者...VC传入一个结构的指针,这样的话VC和DLL可以共同操作这个结构,用啥filemap喔

5楼: kkyy:
"上次传入的在DLL里面保留啊"
"VC传入一个结构的指针,这样的话VC和DLL可以共同操作这个结构"
恕我愚笨,请问如何实现,详细一点好吗?多谢了.

6楼: 也就是你要在dll中保存调用init时的参数啊,如果不保存调用GetInitParams时怎么获得那些参数呢?kkyy的方法不错
PTest = ^TTest;
TTest = packed record
Handle: THandle;
Param1: int;
Param2: Pchar
end;
var ATest:TTest;
PATest:PTest;
Atest.handle:= init(Atest.Param1,ATest.Param2);

PATest:= GetInitParams(Atest.handle);

财务软件版7楼: 所有類型一定要是WIN底層的標准WIN類型,也就是說要用WIN的標准類型或聲明。


不然會有很多未知的錯誤的。

8楼: to rabbitlzx,你的方法不行,因为DLL的函数原型已经固定,不能修改.[:(]

9楼: DLL和进程中的其它线和及DLL是共享资源的
也就是说指针指的将是同一个地点
也就是说可以把它当做普通数据来使用

10楼: 读数据方法不对

hMap := CreateFileMapping(DWord($FFFFFFFF), nil, PAGE_READWRITE,
0, DataSize, ShareName);
try
tmpData := MapViewofFile(hMap, FILE_MAP_READ, 0, 0, 0);
move(tmpData^, Data^, DataSize);
UnMapViewofFile(tmpData);
finally
CloseHandle(hMap);
end;

11楼: 不是通过handle来传的,要用内存映像名称

12楼: wisenow:
不能用HANDLE来映射已存在的文件吗?必须用OPENVIEWFILE?阿,这样的话如何来实现上面的要求呢,请给点提示吧. 如金蝶财务软件教程

13楼: Mike1234567890:因为有可能多次调用init函数,也就是有多个不同的参数值,所以要加一个HANDLE来区别取出.

财务软件版14楼: 楼主,你的dll函数原型是什么?
我那么写怎么不行呢

15楼: function init(const pParam:PDgramParam):THandle;stdcall;


不是这样,
Atest.handle:= [red]init(Atest.Param1,ATest.Param2);[/red]
这样传就可以了init(pParam)
而且这个传入的数据[blue]pParam[/blue]直到调用function closeall(thandle):boolean;
才消失,其间也会有再次调用init的可能.所以想到用一个HANDLE来标识.

16楼: 我也不太懂,随便试着说说我的意见,
我想问题出在了Move(pParam,DgramParam,sizeof(TDgramParam));上。
看看该move的源代码是从参数的地址处搬迁。而mapViewOfFile返回的
是一个指针,所以move函数的操作就完成了指针值的拷贝,不是所指内
容的拷贝。你上面形参是一指针常量,返回的指针所指内容是否有效呢?
把内容搬迁一下,不知是否好转。
不太懂,随便讨论一下。

17楼: 帮顶

18楼: 不大懂..

19楼: delphi7程序设计与开发技术大全,
看看吧

20楼: function GetInitParams(hDgram:thandle):integer;stdcall
begin
Result:=-1;
hFile:= CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,
0,
SizeOf(TDgramParam),
MEM_FILENAME); // 标识被存映像的是它 --- MEM_FILENAME

if hDgram>0 then
DgramParam := MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if DgramParam<>nil then
Result:=DgramParam.param1;
UnMapViewofFile(DgramParam);

CloseHandle(hFile); // 在同一个dll中的话你要测试一下,看是不是可以(不是能不能的问题,是应该不应该的问题)close掉,如果不是同一个dll那就要close这个handle了

end;

财务软件版21楼: 难道 不能根据一个传入的HANDLE去映射上次那个MAPFILE吗?根据 MEM_FILENAME不行阿,函数原型就传的HANDLE过来的/

22楼: 我的意思是mapViewOfFile所返回的指针永远都不需要改变,因为这是共享信息的地址,
是openFileMapping或createFileMapping返回MEM_FILENAME标识的唯一地址,也是将来顺藤摸瓜的依据。因此DgramParam为何又经过move将先前map的值冲掉呢?
许是我的想法错误,讨论讨论。 如用友erp软件

23楼: 谢谢各位朋友,我采取另一种实现方式.现送分.