0

//德尔福代码

procedure SendData(data:pointer;size:cardinal); stdcall;
   begin
    c.SendData(data,size);
   end;

  function GetEvent(out tag:cardinal):integer; stdcall;
   begin
    result:=0;
    if qEnd<>qStart then begin
     result:=queue[qStart].eventCode;
     tag:=queue[qStart].eventTag;
     inc(qStart);
    end;
   end;

  function GetMessage(handle:cardinal;out data:pointer):cardinal; stdcall;
   begin
    result:=GetMsg(handle,data);
   end;

我正在使用 unity3d 引擎,使用它的 c#。我需要集成和调用从delphi创建的dll文件。

所以我用c#写了,

using UnityEngine;
using System.Collections;
using System; 
using System.Text; 
using System.Collections.Generic; 
using System.Runtime.InteropServices;

public class test : MonoBehaviour {
    [DllImport ("ServerTool")]
    private static extern void Connect(int a);
    [DllImport ("ServerTool")]
    private static extern int GetEvent();
    [DllImport ("ServerTool")]
    private static extern void SendData(IntPtr p,  int b);

    // Use this for initialization
    void Start () {
        Connect(0);

        SendData("asdf", 1);
        Debug.Log(GetEvent());
    }

    // Update is called once per frame
    void Update () {

    }
}

这发生错误说,

Assets/test.cs(20,17): error 1502: The best overloaded method match for test.SendData(System.IntPtr, int) has some invalid arguments Assets/test.cs(20,17): error 1503: Argument / #/1 无法将字符串表达式转换为类型 `System.IntPtr'

我对delphi不太了解,但是指针是类似c#的对象,不是吗?所以我尝试将 IntPtr 更改为 object,然后编译完成,但是运行代码时出现错误,

MarshalDirectiveException: 类型对象的编组未实现 test.Start () (在 Assets/test.cs:20)

那么如何从c#调用上面的delphi的SendData函数呢?

谢谢。

4

2 回答 2

1

您必须使用 C# 的编组:

在您的情况下,您必须使用 Marshal.StringToHGlobalAnsi 将 String 转换为 IntPtr,它接受一个字符串参数并返回一个 IntPtr。

请参阅 MSDN 文档:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.stringtohglobalansi.aspx

正如大卫所说,您还必须使用 FreeHGlobal。

于 2012-06-19T06:01:17.380 回答
0

指针类型应该没问题。你的整数是错误的。Delphi 中的基数是一个 32 位长的无符号整数(0 到 4294967295)。DocWiki 参考

于 2012-06-19T09:30:09.763 回答