因为一个项目的需要,在DLL的导出函数中使用了一个函数指针的参数,函数原型为:
public static int BusinessPackage(TMessage485[] pack485, int recCount,ref TMessage485[] returnPack485,int sendCount, int count)
定义的委托:
public delegate int dlBussPack485(TMessage485[] pack485, int recCount, ref TMessage485[] returnPack485, int sendCount, int count);
DLL引用声明为:
[DllImport(DLLName, CharSet = CharSet.Ansi)]
public static extern Boolean RunServer(int outTime, int sendTime, int port,[MarshalAs(UnmanagedType.FunctionPtr)] dlBussPack485 dealFunc);DLL为delphi7开发,原型为:
//启动服务
//outTime:接收数据超时 sendTime:处理数据超时
//port:开启服务端口 func 指定业务逻辑处理函数指针
//返回 True表示成功启动服务,False表示启动失败
function RunServer(outTime:integer;sendTime:integer;port:integer;func :TBusinessPackege):boolean;stdcall;
TBusinessPackege = function(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer) : integer;
因为语言问题,两边的参数上不一致的。DELPHI中ARRAY传递的时候需要在后面指定一个长度,才能保证调用成功。
在这个的基础我另外申明另外一个函数:
function BusinessPackageT(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer):integer;stdcall;
此函数在C#中的申明为:
public static extern int BusinessPackageT(TMessage485[] pack485,int recCount, ref TMessage485[] returnPack485,int sendCount, int count);
这个函数调用是正常的,参数和结果都很正确。上面那个传递的函数指针就不能运行了,一运行就会抱错,整个程序自动关闭。
托管调试助手“FatalExecutionEngineError”在“D:\我的文档\桌面\工位阅读器DEMO\RFIDSERVER\RFIDSERVER\bin\Debug\RFIDSERVER.exe”中检测到故障。
其他信息: 运行库遇到了错误。此错误的地址为 0x79e9e1b0,在线程 0xd54 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
本人功力不够,还请高手指点一二!
public static int BusinessPackage(TMessage485[] pack485, int recCount,ref TMessage485[] returnPack485,int sendCount, int count)
定义的委托:
public delegate int dlBussPack485(TMessage485[] pack485, int recCount, ref TMessage485[] returnPack485, int sendCount, int count);
DLL引用声明为:
[DllImport(DLLName, CharSet = CharSet.Ansi)]
public static extern Boolean RunServer(int outTime, int sendTime, int port,[MarshalAs(UnmanagedType.FunctionPtr)] dlBussPack485 dealFunc);DLL为delphi7开发,原型为:
//启动服务
//outTime:接收数据超时 sendTime:处理数据超时
//port:开启服务端口 func 指定业务逻辑处理函数指针
//返回 True表示成功启动服务,False表示启动失败
function RunServer(outTime:integer;sendTime:integer;port:integer;func :TBusinessPackege):boolean;stdcall;
TBusinessPackege = function(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer) : integer;
因为语言问题,两边的参数上不一致的。DELPHI中ARRAY传递的时候需要在后面指定一个长度,才能保证调用成功。
在这个的基础我另外申明另外一个函数:
function BusinessPackageT(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer):integer;stdcall;
此函数在C#中的申明为:
public static extern int BusinessPackageT(TMessage485[] pack485,int recCount, ref TMessage485[] returnPack485,int sendCount, int count);
这个函数调用是正常的,参数和结果都很正确。上面那个传递的函数指针就不能运行了,一运行就会抱错,整个程序自动关闭。
托管调试助手“FatalExecutionEngineError”在“D:\我的文档\桌面\工位阅读器DEMO\RFIDSERVER\RFIDSERVER\bin\Debug\RFIDSERVER.exe”中检测到故障。
其他信息: 运行库遇到了错误。此错误的地址为 0x79e9e1b0,在线程 0xd54 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
本人功力不够,还请高手指点一二!
那个回调函数的作用是来做数据处理的。
DELPHI调用原码,
dynaFunc 为上面定义的:
TBusinessPackege = function(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer) : integer;
调用原码
function TServerThread.DynamicBusinessPackage(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer):integer;
begin
try
begin
if Assigned(dynaFunc) then
result := dynaFunc(pack485, returnPack485,count)
else result := 0;
end
except on E :Exception do
begin
result := e.HelpContext;
end;
end;
end;昨天开始发现这个问题,还没有解决!实在是惭愧。
还请进一步指点,我这里也在找相关资料!谢谢。
public delegate int dlBussPack485([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct, SizeConst = 61)]TMessage485[] pack485, int reccount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct, SizeConst = 61)] TMessage485[] returnPack485, int returnCount, int count);
我把委托申明成这样后,可以调用,只有2个问题,1 returnPack485这个参数传入错误,也就是说里面的数据不对,2 这个参数需要按引用传递进来的,可是如果用REF调用后,是NULL的。
/// 业务逻辑处理接收包,并返回
/// </summary>
/// <param name="pack485">接收的485包</param>
/// <param name="recCount">接收的包数量</param>
/// <param name="returnPack485">返回的包</param>
/// <param name="returnCount">返回的包长度</param>
/// <param name="count">有效的接收包数量</param>
/// <returns>有效的返回包数量</returns>
public int BusinessPackage(TMessage485[] pack485, int recCount, [In, Out] TMessage485[] returnPack485, int returnCount, int count)