在VC中调用一个DLL(DELPHI写的)一个函数(很难的问题,分不够再加)(200分)

  • 主题发起人 主题发起人 eire
  • 开始时间 开始时间
E

eire

Unregistered / Unconfirmed
GUEST, unregistred user!
问题:<br> &nbsp;在VC中调用一个DLL(DELPHI写的)一个函数,并传入参数,由DLL 生成一个句柄HANDLE返回给VC,下次VC调用这个DLL中的另一个函数时传入这个HANDLE,在DLL中如何根据这个传入的句柄得到上次VC传入的那些参数值?<br><br>1.用内存映射文件方式吗?<br>function init(const pParam:PDgramParam):THandle;stdcall;<br>begin<br> &nbsp;Result:=0;<br> &nbsp;hFile:= CreateFileMapping($FFFFFFFF,nil,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PAGE_READWRITE,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SizeOf(TDgramParam),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MEM_FILENAME);<br> &nbsp;if hFile = INVALID_HANDLE_VALUE then &nbsp;Exit;<br><br> &nbsp;DgramParam:= MapViewOfFile(hFile,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;File_MAP_WRITE,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0);<br> &nbsp;if DgramParam =nil then Exit;<br> &nbsp;Move(pParam,DgramParam,sizeof(TDgramParam));<br> &nbsp;Result:=hFile;<br>end;<br><br>function GetInitParams(hDgram:thandle):integer;stdcall<br>begin<br> &nbsp;Result:=-1;<br> &nbsp;if hDgram&gt;0 then<br> &nbsp; &nbsp; [red]DgramParam [/red]:= MapViewOfFile(hDgram, FILE_MAP_ALL_ACCESS, 0, 0, 0);<br> &nbsp;if DgramParam&lt;&gt;nil then<br> &nbsp; &nbsp; Result:=DgramParam.param1;<br>end; <br>说明:<br> &nbsp; 我在DELPHI中测试,调用DLL中上面两个函数,首先调用init函数,并保存其返回的HANDLE,然后调用DLL中的另一个函数GetInitParams并传入上次返回的HANDLE.但[red]DgramParam[/red] 始终为NIL,不知为何.<br>不知还有其他解决方案没有.
 
顶.........
 
i不太明白,学习
 
上次传入的在DLL里面保留啊,或者...VC传入一个结构的指针,这样的话VC和DLL可以共同操作这个结构,用啥filemap喔
 
kkyy:<br>&quot;上次传入的在DLL里面保留啊&quot;<br>&quot;VC传入一个结构的指针,这样的话VC和DLL可以共同操作这个结构&quot;<br>恕我愚笨,请问如何实现,详细一点好吗?多谢了.
 
也就是你要在dll中保存调用init时的参数啊,如果不保存调用GetInitParams时怎么获得那些参数呢?kkyy的方法不错<br>PTest = ^TTest;<br>TTest = packed record<br> Handle: THandle;<br> Param1: int;<br> Param2: Pchar<br>end;<br>var ATest:TTest;<br> &nbsp; &nbsp;PATest:PTest;<br> Atest.handle:= init(Atest.Param1,ATest.Param2);<br><br> PATest:= GetInitParams(Atest.handle);
 
所有類型一定要是WIN底層的標准WIN類型,也就是說要用WIN的標准類型或聲明。<br>不然會有很多未知的錯誤的。
 
to rabbitlzx,你的方法不行,因为DLL的函数原型已经固定,不能修改.[:(]
 
DLL和进程中的其它线和及DLL是共享资源的<br>也就是说指针指的将是同一个地点<br>也就是说可以把它当做普通数据来使用
 
读数据方法不对<br><br> &nbsp;hMap := CreateFileMapping(DWord($FFFFFFFF), nil, PAGE_READWRITE,<br> &nbsp; &nbsp;0, DataSize, ShareName);<br> &nbsp;try<br> &nbsp; &nbsp;tmpData := MapViewofFile(hMap, FILE_MAP_READ, 0, 0, 0);<br> &nbsp; &nbsp;move(tmpData^, Data^, DataSize);<br> &nbsp; &nbsp;UnMapViewofFile(tmpData);<br> &nbsp;finally<br> &nbsp; &nbsp;CloseHandle(hMap);<br> &nbsp;end;
 
不是通过handle来传的,要用内存映像名称
 
wisenow:<br> 不能用HANDLE来映射已存在的文件吗?必须用OPENVIEWFILE?阿,这样的话如何来实现上面的要求呢,请给点提示吧.
 
Mike1234567890:因为有可能多次调用init函数,也就是有多个不同的参数值,所以要加一个HANDLE来区别取出.
 
楼主,你的dll函数原型是什么?<br>我那么写怎么不行呢
 
function init(const pParam:PDgramParam):THandle;stdcall;<br>不是这样,<br>Atest.handle:= [red]init(Atest.Param1,ATest.Param2);[/red]<br>这样传就可以了init(pParam)<br>而且这个传入的数据[blue]pParam[/blue]直到调用function closeall(thandle):boolean;<br>才消失,其间也会有再次调用init的可能.所以想到用一个HANDLE来标识.
 
我也不太懂,随便试着说说我的意见,<br>我想问题出在了Move(pParam,DgramParam,sizeof(TDgramParam));上。<br>看看该move的源代码是从参数的地址处搬迁。而mapViewOfFile返回的<br>是一个指针,所以move函数的操作就完成了指针值的拷贝,不是所指内<br>容的拷贝。你上面形参是一指针常量,返回的指针所指内容是否有效呢?<br>把内容搬迁一下,不知是否好转。<br>不太懂,随便讨论一下。
 
不大懂..
 
delphi7程序设计与开发技术大全,<br>看看吧
 
function GetInitParams(hDgram:thandle):integer;stdcall<br>begin<br> &nbsp;Result:=-1;<br> &nbsp;hFile:= CreateFileMapping($FFFFFFFF,nil,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PAGE_READWRITE,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SizeOf(TDgramParam),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MEM_FILENAME); &nbsp;// 标识被存映像的是它 --- MEM_FILENAME<br><br> &nbsp;if hDgram&gt;0 then<br> &nbsp; &nbsp; DgramParam := MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);<br> &nbsp;if DgramParam&lt;&gt;nil then<br> &nbsp; &nbsp; Result:=DgramParam.param1;<br> &nbsp;UnMapViewofFile(DgramParam);<br> &nbsp;<br> &nbsp;CloseHandle(hFile); &nbsp;// 在同一个dll中的话你要测试一下,看是不是可以(不是能不能的问题,是应该不应该的问题)close掉,如果不是同一个dll那就要close这个handle了<br> <br>end;
 
后退
顶部