首页 新闻 会员 周边

C#调用delphi的DLL问题,大家帮我看下

0
悬赏园豆:60 [已关闭问题] 关闭于 2013-10-08 10:32
有一个delphi的DLL中的方法我想在C#中用,其说明文档中这样描述的
函数定义:function SajetTransData(f_iCommandNo : integer;f_pData,f_pLen : pointer) : boolean; stdcall; 
参数一:f_iCommandNo:型態為integer指定此次資料所要執行的工作
参数二:f_pData:型態為pointer,其值為一連續記憶體空間(例如ARRAY OF BYTE)的起始位置,當執行完FUNCTION後,MES系統也會將要回傳的資料放到這個記憶體空間,這個記憶體空間的可為動態陣列或固定陣列,但最小長度須為100
参数三:f_pLen:型態為integer的pointer,用來儲放f_pData內資料的有效長度
我的调用如下:先声明   
[DllImport(@"SajetConnect.dll", CharSet = CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
public static extern  Boolean SajetTransData(int f_iCommandNo, String f_pData, IntPtr f_pLen);
然后应用:  private void button3_Click(object sender, EventArgs e)
        {
            string s1 = "SAJET001;";
            byte[] b1 = Encoding.Default.GetBytes(s1);
            int refInt = b1.Length;
            int iCommand = 1;

            var sss = SajetTransData(iCommand,s1, (intPtr)refInt);
            MessageBox.Show(sss.ToString());
报错,有这方面经验的同志可否帮我看下
范立勇的主页 范立勇 | 初学一级 | 园豆:20
提问于:2013-08-09 10:33
< >
分享
所有回答(6)
0

我不看,打死都不看,这种问题太坑爹了。

Launcher | 园豆:45045 (高人七级) | 2013-08-09 10:46

你说的话我就不喜欢听,什么叫打死都不看,什么叫坑爹,你不看自有人看,你不帮忙自有人帮忙,实在不行,问题先空这,一年之后再来解决

支持(0) 反对(0) 范立勇 | 园豆:20 (初学一级) | 2013-08-09 20:55
0
dudu | 园豆:31007 (高人七级) | 2013-08-09 11:20

报错的具体内容是什么?

支持(0) 反对(0) dudu | 园豆:31007 (高人七级) | 2013-08-11 17:16

@dudu: 

程序是这样调用的:

 [DllImport(@"SajetConnect.dll", EntryPoint = "SajetTransData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Boolean SajetTransData(int f_iCommandNo,   IntPtr f_pData,  IntPtr f_pLen);

 

调用方式:
string s1 = "SAJET001;";
byte[] bArray = new byte[500];
bArray = Encoding.Default.GetBytes(s1);
byte[] bbb = ReadBytesFromPtr(firstAdd, 500);
IntPtr inpPtrTest = new IntPtr();
WriteBytesToPtr(inpPtrTest, bArray);
var sss = SajetTransData(iCommand,  inpPtrTest, (IntPtr)f_pLen);还是不对

支持(0) 反对(0) 范立勇 | 园豆:20 (初学一级) | 2013-08-11 17:55

@范立勇: 

将 

public static extern Boolean SajetTransData(int f_iCommandNo,   IntPtr f_pData,  IntPtr f_pLen);

改为:

public static extern Boolean SajetTransData(int f_iCommandNo, 
    [MarshalAs(UnmanagedType.LPStr)] string f_pData, 
    [MarshalAs(UnmanagedType.LPStr)] int f_pLen);

然后直接用int, string, int这三个参数类型调用试试

支持(0) 反对(0) dudu | 园豆:31007 (高人七级) | 2013-08-11 18:14
0

首先贴出我的测试代码:

delphi:(Delphi指针不太会,还请大神们指点)

unit Unit1;

interface
uses
  SysUtils;

function SajetTransData(f_iCommandNo:Integer;f_pData,f_pLen:Pointer):Boolean;stdcall;

implementation

function SajetTransData(f_iCommandNo:Integer;f_pData,f_pLen:Pointer):Boolean;
var
  str,strlen:string;
  len:Integer;
  pstr:PChar;
  plen,i:Integer;
begin
  Result:=False;

  if f_iCommandNo=1 then
  begin
    str:='';
    strlen:='';
    while Char(f_pData^) <> #0 do
    begin
      str := str +string(Char(f_pData^));
      inc(Integer(f_pData));
    end;
    while Char(f_pLen^) <> #0 do
    begin
      strlen := strlen +string(Char(f_pLen^));
      inc(Integer(f_pLen));
    end;
    len:=StrToInt(strlen);
    str:=#13+'原始字符串:'+str+#13+
      '有效长度:'+IntToStr(len);
    pstr:=PChar(str);
    plen:=Length(str);
    for i:=0 to plen do
    begin
      Char(f_pData^):=pstr[i];
      inc(Integer(f_pData));
    end;
    Char(f_pData^):=#0;
  end;

  Result:=True;
end;

end.
Delphi测试代码

C#测试代码:

private void button2_Click(object sender, EventArgs e)
        {
            int f_iCommandNo;
            StringBuilder f_pData=new StringBuilder(256);
            StringBuilder f_pLen = new StringBuilder(256);
            f_iCommandNo = 1;
            f_pData.Append("123");
            f_pData.Append("45");
            int len = f_pData.Length;
            f_pLen.Append(len.ToString());
            CallDelphi.SajetTransData(f_iCommandNo,f_pData,f_pLen);
            MessageBox.Show(f_pData.ToString());
        }

        private class CallDelphi
        {
            const string path = "CsharpTest.dll";
            [DllImport(path, EntryPoint = "SajetTransData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern Boolean SajetTransData(int f_iCommandNo, StringBuilder f_pData, StringBuilder f_pLen);
        }
C# 测试代码

两个指针都用StringBuild去操作。f_pLen传入int型的即可。

测试结果(第一行为原数据,后面为delphi处理后在原指针上加的内容):

FoolRabbit | 园豆:202 (菜鸟二级) | 2013-08-14 14:02
0

我觉得沙里JIN的回答有点道理。

向北方 | 园豆:154 (初学一级) | 2013-08-19 18:25
0

谢谢

范立勇 | 园豆:20 (初学一级) | 2013-10-08 10:31
0

你好,群主,你这个问题,解决了吗?可否赐教一下?

站在树枝上 | 园豆:204 (菜鸟二级) | 2015-12-22 12:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册