delphi代码转C#代码的问题

小_菜1 2019-05-31 04:03:09
 public struct PTask
{
public IntPtr command; // 命令,4位
public IntPtr taskType; // 任务类型,4位
public IntPtr taskID; // 任务ID,32位
public IntPtr srcTaskID; // 最初任务ID,32位
public IntPtr srcRequesterID; // 最初请求方ID,12位
public IntPtr senderID; // 发送方ID,12位
public IntPtr receiverID; // 接收方ID,每个12位
public IntPtr priority; // 优先级,1位
public IntPtr isACK; // 是否要求回执,1位
public IntPtr invalidation; // 失效时间,13位
public IntPtr sentTime; // 数据发送时间,14位
public IntPtr taskName; // 任务名称,32位
public IntPtr taskBody; // 任务体
}
[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sendTask(ref PTask task, IntPtr ip, IntPtr port);


[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr receiveTask(ref PTask task, IntPtr ip, IntPtr port, ref bool other);


[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern string errorCodeTrans(IntPtr name);


[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern string free_char(IntPtr name);

public string GetPCI(string sCode)
{
string result = string.Empty;
PTask oTask;
PTask oTask2;
IntPtr iTask = IntPtr.Zero;
IntPtr iRet = IntPtr.Zero;
string sError = string.Empty;
string sRet = string.Empty;
string sTask = string.Empty;
bool bTmp;
int i = 0;
IntPtr sIp = IntPtr.Zero;
IntPtr sPort = IntPtr.Zero;
try
{
result = "";
oTask = new PTask();
oTask.senderID = Marshal.StringToHGlobalAnsi(PopSendId);
oTask.receiverID = Marshal.StringToHGlobalAnsi(PopReceiveId);
oTask.taskName = Marshal.StringToHGlobalAnsi("query");
oTask.taskBody = Marshal.StringToHGlobalAnsi(GetBody(sCode));
//oTask.taskBody = Marshal.StringToCoTaskMemAuto(GetBody(sCode));
sIp = Marshal.StringToHGlobalAnsi(PopIp);
sPort = Marshal.StringToHGlobalAnsi(PopPort);
iTask = sendTask(ref oTask, sIp, sPort);
sTask = Marshal.PtrToStringAnsi(iTask);
if (sTask.Length != 32)
{
sError = errorCodeTrans(iTask);
free_char(iTask);
}
bTmp = true;
oTask2 = new PTask();
oTask2.senderID = Marshal.StringToHGlobalAnsi(PopSendId);
oTask2.receiverID = Marshal.StringToHGlobalAnsi(PopReceiveId);
oTask2.taskName = Marshal.StringToHGlobalAnsi("query");
oTask2.taskBody = Marshal.StringToHGlobalAnsi("");
oTask2.srcTaskID = Marshal.StringToHGlobalAnsi(sTask.Substring(0, sTask.Length - 1));
//free_char(iTask);
Thread.Sleep(3000);
for (i = 1; i <= 20; i++)
{
iRet = receiveTask(ref oTask2, sIp, sPort, ref bTmp);
sRet = Marshal.PtrToStringAnsi(iRet);
if (sRet != null)
{
if (sRet.Length == 4)
{
sError = errorCodeTrans(iTask);
free_char(iRet);
//Units.uUserThread.error(sError);
}
else
{
result = sRet;
free_char(iRet);
}
break;
}
}
}
catch (Exception Ex)
{
throw new Exception(Ex.Message);
}
return result;
}

  TTask=record
command:pchar; // 命令,4位
taskType:pchar; // 任务类型,4位
taskID:pchar; // 任务ID,32位
srcTaskID:pchar; // 最初任务ID,32位
srcRequesterID:pchar; // 最初请求方ID,12位
senderID:pchar ; // 发送方ID,12位
receiverID:pchar; // 接收方ID,每个12位
priority:pchar; // 优先级,1位
isACK:pchar; // 是否要求回执,1位
invalidation:pchar; // 失效时间,13位
sentTime:pchar; // 数据发送时间,14位
taskName:pchar; // 任务名称,32位
taskBody:pchar; // 任务体
end;
function sendTask(task:PTask;ip:pchar;port:pchar):pchar;cdecl;external 'PCI2.DLL';
function receiveTask(task:PTask;ip:pchar;port:pchar;other:PBool):pchar;cdecl;external 'PCI2.DLL';
function errorCodeTrans(name:pchar):pchar;cdecl;external 'PCI2.DLL';
function free_char(name:pchar):pchar;cdecl;external 'PCI2.DLL';
function TPopThread.GetPCI(sCode: String):String;
var
oTask,oTask2:TTask;
sTask,sError,sRet:pchar;
bTmp:boolean;
i:integer;
sIp,sPort:pchar;
begin
try
try
Result:='';
ZeroMemory(@oTask,SizeOf(TTask));
oTask.senderID:=pchar(Global.GetConfig('PopSendId'));
oTask.receiverID:=pchar(Global.GetConfig('PopReceiveId'));
oTask.taskName:='query';
oTask.taskBody:=pchar(getBody(sCode));
sIp:=pchar(Global.GetConfig('PopIp'));
sPort:=pchar(Global.GetConfig('PopPort'));
sTask:=sendTask(@oTask,sIP,sPort);
try
if length(sTask)<>32 then
begin
sError:=errorCodeTrans(sTask);
free_char(sTask);
error(sError);
end;
finally
//free_char(sTask);
end;
bTmp:=true;
ZeroMemory(@oTask2,SizeOf(TTask));
oTask2.senderID:=pchar(Global.GetConfig('PopSendId'));
oTask2.receiverID:=pchar(Global.GetConfig('PopReceiveId'));
oTask2.taskName:='query';
oTask2.taskBody:='';
oTask2.srcTaskID:=PChar(Copy(sTask,1,Length(sTask)));
free_char(sTask);
Sleep(StrToInt(Global.GetConfig('PopSleepTime')));
for i:=1 to 20 do
begin
sRet:=ReceiveTask(@oTask2,pchar(sIp),pchar(sPort),@bTmp);
if sRet<>nil then
try
if length(sRet)=4 then
begin
sError:=errorCodeTrans(sTask);
free_char(sRet);
error(sError);
end
else
begin
Result:=sRet;
free_char(sRet);
end;
break;
finally
//free_char(sRet);
end;
Sleep(StrToInt(Global.GetConfig('PopSleepTime')));
end;
except
on Ex:Exception do
begin
RaiseError(Ex,'GetPCI');
end;
end;
finally

end;
end;

2个都是调用的c++动态库 ,delphi运行正常 , c#返回的是请求报文格式不正确 , 求大佬帮帮忙
...全文
1561 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2019-06-05
  • 打赏
  • 举报
回复
这种就不纠结了,把delphi的写成一个dll,让delphi的中间代理访问就好。 你跟我不对付,我找个能跟你对付的人去做
OrdinaryCoder 2019-06-05
  • 打赏
  • 举报
回复
引用 21 楼 小_菜1 的回复:
引用 20 楼 OrdinaryCoder 的回复:
我觉得你还是找一下C++的接口定义 如果是用别的公司的SDK 那么会有说明 如果是自己公司的 源码都会有
别的公司的,很多年前的,

最好还是找一找 你现在用delphi代码 改成C# 很多数据格式都得猜 得一个一个试验 老费劲了 而且像这种库类C++DLL 应该是会有相应的头文件的 里面有接口定义
小_菜1 2019-06-05
  • 打赏
  • 举报
回复
引用 20 楼 OrdinaryCoder 的回复:
我觉得你还是找一下C++的接口定义 如果是用别的公司的SDK 那么会有说明 如果是自己公司的 源码都会有
别的公司的,很多年前的,
OrdinaryCoder 2019-06-05
  • 打赏
  • 举报
回复
我觉得你还是找一下C++的接口定义 如果是用别的公司的SDK 那么会有说明 如果是自己公司的 源码都会有
小_菜1 2019-06-05
  • 打赏
  • 举报
回复
引用 16 楼 soaringbird 的回复:
[quote=引用 15 楼 小_菜1 的回复:]
结构定义里的每个成员的位数,是bit还是字符数?
没定义位数,因为没有原型,给的delphi里面没有也就没定义
被风吹过灼 2019-06-04
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
那个结构成员全是指针,不会有结构对齐尺寸导致的问题
如果还不行,你可以考虑用一下unsafe
public unsafe struct PTask
{
public byte *command;
public byte *taskType;
// ...
}
soaringbird 2019-06-04
  • 打赏
  • 举报
回复
[quote=引用 15 楼 小_菜1 的回复:] 结构定义里的每个成员的位数,是bit还是字符数?
小_菜1 2019-06-04
  • 打赏
  • 举报
回复
引用 14 楼 soaringbird 的回复:
那个结构体的定义,在C#和Delphi中,内存布局要完全一致,对齐方式要一致,就是把结构中所有的成员依次排列到一起,就是一个byte数组,像你的定义里面,那些半个字节、1比特的成员能组合成整字节的就组合成整字节的,或者写一个方法从字节数组的某个偏移量取出多少来转换,那个taskbody,也要能展开成字节数组放进来。就是整个结构体,要能当做一个字节数组用
主要是我没有原型,只能通过delphi代码去转成c#代码
小_菜1 2019-06-03
  • 打赏
  • 举报
回复
有大佬吗,帮忙看看问题。
soaringbird 2019-06-03
  • 打赏
  • 举报
回复
那个结构体的定义,在C#和Delphi中,内存布局要完全一致,对齐方式要一致,就是把结构中所有的成员依次排列到一起,就是一个byte数组,像你的定义里面,那些半个字节、1比特的成员能组合成整字节的就组合成整字节的,或者写一个方法从字节数组的某个偏移量取出多少来转换,那个taskbody,也要能展开成字节数组放进来。就是整个结构体,要能当做一个字节数组用
小_菜1 2019-06-03
  • 打赏
  • 举报
回复
引用 10 楼 早打大打打核战争 的回复:
你应该把整个结构体放在unmanaged memory中:
[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sendTask(IntPtr task, IntPtr ip, IntPtr port);
我这么用就还是格式不正确
小_菜1 2019-06-03
  • 打赏
  • 举报
回复
引用 10 楼 早打大打打核战争 的回复:
你应该把整个结构体放在unmanaged memory中:
[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sendTask(IntPtr task, IntPtr ip, IntPtr port);
但是会报这个错误。
小_菜1 2019-06-03
  • 打赏
  • 举报
回复
引用 10 楼 早打大打打核战争 的回复:
你应该把整个结构体放在unmanaged memory中:
[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sendTask(IntPtr task, IntPtr ip, IntPtr port);
大哥 意思是我需要在传结构体的时候 使用intPtr传输是吗 。那么我的代码是不是应该这么写:
sPort = Marshal.StringToHGlobalAnsi(PopPort);
IntPtr intpt = Marshal.AllocHGlobal(Marshal.SizeOf(oTask)); //对intpt分配内存
iTask = sendTask(intpt, sIp, sPort);
sTask = Marshal.PtrToStringAnsi(iTask);

大哥 你有企鹅什么的吗
  • 打赏
  • 举报
回复
你应该把整个结构体放在unmanaged memory中:
[DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sendTask(IntPtr task, IntPtr ip, IntPtr port);
小_菜1 2019-05-31
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
[StructLayout(LayoutKind.Sequential)]
public struct PTask
这个我加着的 贴代码的时候没有贴上来 我完整的是 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
stherix 2019-05-31
  • 打赏
  • 举报
回复
[StructLayout(LayoutKind.Sequential)] public struct PTask
小_菜1 2019-05-31
  • 打赏
  • 举报
回复
引用 4 楼 OrdinaryCoder 的回复:
C++接口是什么样的 是不是C++和C#类型没对应好
没有给我c++原型,给了delphi的demo delphi我运行了没有问题,我转化的c#就有问题,我是按照delphi定义的类型去定义的c#的。按道理,c++接收的肯定是指针地址。
小_菜1 2019-05-31
  • 打赏
  • 举报
回复
引用 2 楼 耗子哭死猫 的回复:
断点走一下,看看哪行错了,错误信息是什么
2个都是调用的c++动态库 ,delphi运行正常 , c#返回的是请求报文格式不正确 动态库返回错误
OrdinaryCoder 2019-05-31
  • 打赏
  • 举报
回复
C++接口是什么样的 是不是C++和C#类型没对应好
加载更多回复(3)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧