c#调用c++的dll 带byte *的函数怎么传入数据

用c调用一个c++的dll 时,方法的是这样的sent(byte * msg,int msgLen),往dll里传入了byte* msg这个东西,然后获得了返回值,现在我想用 c#来调用,不知道怎么调用。跪求大神指点!

    [DllImport("test.dll")]
    public static extern void sent(IntPtr msg, int msgLen);

    [STAThread]
    public static void Main(string[] args)
    {
        var len = 1000;
        var ar = new byte[len];
        // ar 中设置需要发送的内容 
        var p = Marshal.AllocHGlobal(Marshal.SizeOf(ar));
        Marshal.Copy(ar, 0, p, ar.Length);
        sent(p, len);
        Marshal.FreeHGlobal(p);
    }

追问

我之前有用过你这样的方法处理过不行,其他朋友的方法也有用过不行! C 调用时是这样的:

BISAFE_EXPORT "C" int WINAPI send(long sock, BYTE *buf, int len);

用下面的方法来调用能发送成功,可是以送的数据不完整,只发得了一个byte的数据出去!

能有什么办使我发送的byte完整吗??谢谢!!!

追答

试试下面的办法


    [DllImport("test.dll")]
    public static extern void sent(long socket, IntPtr msg, int len);

    [STAThread]
    public static void Main(string[] args)
    {
        long sslsock = 0;
        const string reqString = @"test";

        // 方法1
        var bytes = Encoding.Default.GetBytes(reqString);
        var p = Marshal.AllocHGlobal(Marshal.SizeOf(bytes));
        Marshal.Copy(bytes, 0, p, bytes.Length);
        sent(sslsock, p, bytes.Length);
        Marshal.FreeHGlobal(p);

        // 方法2
        IntPtr intPtr = Marshal.StringToHGlobalAnsi(reqString);
        sent(sslsock, intPtr, Encoding.Default.GetByteCount(reqString));
        Marshal.FreeHGlobal(intPtr);
    }

追问

第二种方法以前用过了不行,第一种方法用时报错了!

不清楚是不是C调用时 byte* 只是指向一个byte的地址,现在想传byte的数组,或IntPtr都不行,这个dll是没有问题的,不懂要怎么调用才好了?

追答

象下面这样试试看,传入的数组多分配一位,加入一个\0。dll内部应该不是使用unicode字符串的吧

    [DllImport("test.dll")]
    public static extern void sent(long socket, IntPtr msg, int len);

        var bytes = Encoding.Default.GetBytes(reqString);
        var buffer = new byte[bytes.Length + 1];
        Array.Copy(bytes, buffer, bytes.Length);
        var hGlobal = IntPtr.Zero;
        try
        {
            hGlobal = Marshal.AllocHGlobal(buffer.Length);
            Marshal.Copy(buffer, 0, hGlobal, buffer.Length);

//            var debugStr = Marshal.PtrToStringAnsi(hGlobal);
//            Debug.WriteLine(debugStr);

            sent(sslsock, hGlobal, bytes.Length);
        }
        finally
        {
            if (hGlobal != IntPtr.Zero)
                Marshal.FreeHGlobal(hGlobal);
        }

追问

还是不行,引用public static extern int send(long l, byte aPtr, int i);能发送一byte数据,c引用时的这个byte* ,在C#中能有什么办法指向一个byte[] 或intPrt吗?之前试过用循环发送的方法,可获得返回的发送数据长度,与实际不符

追答

函数参数已经是IntPtr了呀。不行在哪里?这样转换字符串至byte数组是没有问题的,我用这段代码调用 SetWindowText 设置记录事,是可以成功调用的。你是不是哪里没注意到。你的调用代码贴出来看看。


设置记事本标题的代码太长,下面是截图

温馨提示:内容为网友见解,仅供参考
第1个回答  2015-10-30
1、添加引用
右击项目-添加引用-浏览 找到本地的dll文件
2、using 该dll文件里面代码的名称空间
然后就可以调用dll文件里面的类(test)和方法(add)了
例如:
using aa.test
namespace conslole1
{
class Program
{
static void Main(string[] args)
{
Test test1=new Test();
test1.add(1, 2);
}
}
}
第2个回答  2013-08-09
byte[] msgBuffer = new byte[ 100];
unsafe
{
fixed (byte* msg= msgBuffer)
{
sent(byte * msg,int msgLen);

}
}
你看这样行不行
第3个回答  2013-08-09
sent(byte []msg,int msflen)或者sent(string msg,int msglen)
相似回答