随手写的,没有测试.
type
FuncA=function(const x:integer;pass:pchar):integer;stdcall;
FuncB=function(x:pchar;pass:pchar):boolean;stdcall;var
p:pointer;
h:hwnd;
begin
if A客户 then
begin
h:=LoadLibrary('a.dll');
if h>0 then
p:=GetProcAddress('abcd');
end
else
begin
h:=LoadLibrary('b.dll');
if h>0 then
p:=GetProcAddress('cccc');
end;
if (p<>nil) then
if a客户 then
FuncA(p)(x,pass)
else
FuncB(p)(x,pass);
end;
type
FuncA=function(const x:integer;pass:pchar):integer;stdcall;
FuncB=function(x:pchar;pass:pchar):boolean;stdcall;var
p:pointer;
h:hwnd;
begin
if A客户 then
begin
h:=LoadLibrary('a.dll');
if h>0 then
p:=GetProcAddress('abcd');
end
else
begin
h:=LoadLibrary('b.dll');
if h>0 then
p:=GetProcAddress('cccc');
end;
if (p<>nil) then
if a客户 then
FuncA(p)(x,pass)
else
FuncB(p)(x,pass);
end;
增加:
type
FuncA=..
FuncB=..
FuncC=procedure....//C客户也
...
if C客户 then
begin
h:=Load....
p:=GetProcAddress(...)
...
end;每次都要更改源代码,那不个好办法啊。
有人提示我用 "插件技术" 做,但我不明白插件技术怎么做?
又有人提示我这么做:
(既然客户的Dll中的函数的返回值与输入参数都是一些基体的数据类型,
那就可以定义一堆函数定义放着)
type
FuncA=procedure(const x:integer);stdcall;
FuncB=procedure(const y:pchar);stdcall;
FuncC=procedure(const z:float):sdtcall;
FuncD=procedure(const x, y:integer);stdcall;
.....
然后在程序调用的时候
h := LoadLibrary(客户的Dll名字);
if 客户的函数定义=FuncA then
begin
p := GetProcAddress( 客户的函数名);
FuncA(p)(..);
end else
if 客户的函数定义=FuncB then
begin
end
....
比如在一个外部的文件里面写明调用的参数的类型,比如Integer,长度比如4,而且要求你的客户更改代码!实际上没有那个语言可以根据什么外部的一个定义来动态的申明什么函数吧?也许有,可能我不知道!
我就想不通,你的程序有这么复杂?需要这样的功能?其实插件的原理也是定义相同的接口!不可能变化的.你看看Winamp的插件的DLL就知道了,就一个Exports函数:WinampGet????()
他有一个专门的基本Cell(类似于AutoCAD中的元件库中的一个元件),专门用来调用
外部的Dll, 其编辑界面简述如下:
外部模块:___________ -----> 即是 Dll名字
例:Email.Dll
功能调用:____________ -----> 即:函数的声明(只支持整数返回)
例:SendEmail(char*, int, char*) //返回int不用写
参数表:______ ----> (多行, 每参数一行),
例: FileName 字符串
Length 两个字节整数 ---->声明了长度
UserName 字符串
华为就是这样做的。(华为SEC里的变量说明的确都声明了长度, 如上例的Length) 不清楚它是怎样实现的。
我也要做一个流程编辑器, 想在流程里把Dll名字, 函数的声明,
输入参数注明。当程序走到这个地方的时候就去调用这个Dll,
然后跟据Dll的返回值再跳转下一个节点。