如何可以通过Dll一次性返回多个字串?(100分)

  • 主题发起人 主题发起人 胡一刀007
  • 开始时间 开始时间

胡一刀007

Unregistered / Unconfirmed
GUEST, unregistred user!
如题!<br>将所有接口模块化,均为DLL类型,其中出现希望一次性返回多个字串,如果不用字符串组合的形式,有何办法?<br>我以类的形式来返回,会报错!不知各位高手有何高见?
 
返回 一个缓冲指针,和缓冲区长度, 或者返回一个数组
 
如果用类的形式返回, 调用模块(EXE)和被调用模块(DLL)对该类的方法地址引用必须是<br>一致的. <br>比如TStrings类, 如果你以标准的编译方式编译你的EXE和DLL, 在最终的程序代码中,<br>TStrings 有两份拷贝—— EXE 程序中有一份,DLL中有一份。很显然它们在程序装入时<br>所处的内存地址不一样。所以不能用做模块间传递的参数。<br>但是如果你以包(Package)方式编译你的EXE和DLL,那么TStrings存在只存在于于<br>VCLxx.bpl中,此时把TStrings类做为模块间传递的参数就是安全的。经实践证明完全可<br>行。<br>
 
可以用共享内存来做。<br><br>unit MapFileUnit;<br><br>interface<br>uses<br>&nbsp; windows;<br>type<br>&nbsp; pCommonData = ^TCommonData;<br>&nbsp; TCommonData = record<br>&nbsp; &nbsp; //CallBackHandle: HWnd;<br>&nbsp; &nbsp; s: array[1..2] of string; //改成你要的内容 <br>&nbsp; end;<br><br>procedure MapCommonData(var CommonData:pCommonData;var HMapFile:THandle);<br>procedure UnMapCommonData(var CommonData:pCommonData;var HMapFile:THandle);<br><br>implementation<br><br>procedure MapCommonData(var CommonData:pCommonData;var HMapFile:THandle);<br>var FirstCall: Boolean;<br>begin<br>&nbsp; HMapFile:=OpenFileMapping(FILE_MAP_WRITE, False, 'ZHUWEI_KEYBOARD');<br>&nbsp; FirstCall:=(HMapFile = 0);<br>&nbsp; if FirstCall then<br>&nbsp; &nbsp; HMapFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0,SizeOf(TCommonData),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'ZHUWEI_KEYBOARD');<br>&nbsp; CommonData:= MapViewOfFile(HMapFile, FILE_MAP_WRITE, 0, 0, 0);<br>&nbsp; if FirstCall then FillChar(CommonData^, SizeOf(TCommonData), 0);<br>end;<br><br>procedure UnMapCommonData(var CommonData:pCommonData;var HMapFile:THandle);<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; UnMapViewOfFile(CommonData);<br>&nbsp; &nbsp; CommonData := nil;<br>&nbsp; &nbsp; CloseHandle(HMapFile);<br>&nbsp; &nbsp; HMapFile := 0;<br>&nbsp; except<br>&nbsp; &nbsp; &nbsp; MessageBox(0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Error when free MapViewFile',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'ZW Hook Error',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_OK);<br>&nbsp; end; //try<br>end;<br><br>end.<br><br>--------------------------<br>调用时:<br>var<br>&nbsp; HMapFile:THandle;<br>&nbsp; CommonData:pCommonData;<br><br>procedure DLlMain(dwReason: DWORD); <br>begin <br>&nbsp; case dwReason of<br><br>&nbsp; &nbsp; DLL_PROCESS_ATTACH:<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; HMapFile:=0;<br>&nbsp; &nbsp; &nbsp; MapCommonData(CommonData,HMapFile);<br>&nbsp; &nbsp; end; // &nbsp;DLL_PROCESS_ATTACH:<br><br>&nbsp; &nbsp; DLL_PROCESS_DETACH:<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if CommonData&lt;&gt;nil then UnMapCommonData(CommonData,HMapFile);<br>&nbsp; &nbsp; end; // DLL_PROCESS_DETACH:<br>&nbsp; &nbsp; <br>&nbsp; end; //calse<br>end;
 
首先,谢谢各位楼上的!<br>To tseug:如您所述,如缓冲区的话,不也要自己接收时加入分割字串。<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 至于数组,好象是不可以在执行程序中这样做的,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 如function (A:THandle):array of string;StdCall;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 这会出错的!且我用TStringList也不可以啊!<br>To skyweb: 如用包的形式来写,不就与写控件差不多,缺乏通用性,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 因为所有接口的动态链接库是模块化且开发工具均有所不同。<br>To zw84611:有没有简单一点的方法?<br>以上是个人想法,也许学识浅薄,还望各位楼上楼下的指正!
 
我在程序里是这么用的<br>foo(a: THandle): PChar; stdcall;<br><br>然后 <br>&nbsp; l := TStringList.Create;<br>&nbsp; l.Text := foo(a);<br>&nbsp; ....<br>&nbsp; l.Free; <br><br>或者<br>&nbsp;type<br>&nbsp; &nbsp; TStrArray = array[1..10] of ShortString;<br><br>&nbsp;foo(a: THandle): TStrArray; stdcall;<br><br>
 
包编译方式只是确定你的程序中要不要包含某些程序代码, 或者是将它们放在<br>Runtime Package中, 与写控件根本是两回事. <br>不过如果你的开发工具并不统一的话, 把类当做参数进行传递的确是行不通的:)<br><br>在一个返回值中包含多个串, 用字符串组合应该是很好的办法了, 有什么理由不用吗?<br>
 
同意tseug的做法, 也可以自己定義一個結構體, 然後就可以返回不同的類型了.
 
用不着这么复杂吧!!<br>只要在DLL中定义一个返回类型为:Tstringlist的就可以了!
 
需把字符串转换为数组。
 
后退
顶部