C#调用C++数组,结构体DLL

1.基本数据类型的传递

常见数据类型的传递

 

C/C++

C#

长度

short

short

2Bytes

int

int

4Bytes

long(该类型在传递的时候常常会弄混)

int

4Bytes

bool

bool

1Byte

char(Ascii码字符)

byte

1Byte

wchar_t(Unicode字符,该类型与C#中的Char兼容)

char

2Bytes

float

float

4Bytes

double

double

8Bytes

 

C++传入、传出C#数组都可以实现,传入数组直接传入,传出数组需要用指针传出。

(1).C++传入数组(测试1加到9

.cpp文件
extern  "C"  __declspec(dllexport) void test(const int N, const int n[], int& Z)
{
    for (int i = 0; i<N; i++)
    {
        Z += n[i];
    }
}

 

.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace Application6
{
    class Program
    {
        [DllImport(@"C:\Users\wdy\Documents\visual studio 2013\Projects\Application5\Debug\Application5.dll", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)]
        public static extern double test(int N, int[] n, ref int Z);

        static void Main(string[] args)
        {
            int N = 0;
            int[] n;
            n = new int[10];
            for (int i = 0; i < 10; i++)
            {
                n[i] = i;
            }
            test(n.Length, n, ref N);
            Console.WriteLine(N.ToString());
            Console.Read();
        }
    }
}

结果:

 

(2).C++传出数组(测试传出结构体数组指针字符串)

.cpp文件
#include "stdafx.h"
#include "Application3.h"


struct cmppe_submit
{
    char user[10][200];
};

extern "C" __declspec(dllexport) void GetUser(cmppe_submit* lpSubit)
{
    strcpy(lpSubit->user[0], "waqerqwdsewf");
}

 

.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace Application4
{
    class Program
    {
        struct cmppe_submit
        {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2000)] 
        public byte[] dst_addr;
        }
        [DllImport(@"C:\users\wdy\documents\visual studio 2013\Projects\Application3\Debug\Application3.dll", EntryPoint = "GetUser", CallingConvention = CallingConvention.Cdecl)]
        private extern static void GetUser(ref cmppe_submit lpSubmit);//用ref声明结构

        static void Main(string[] args)
        
{
    cmppe_submit submit;
    submit.dst_addr = new byte[2000];
    GetUser(ref submit);

    string str = System.Text.Encoding.Default.GetString(submit.dst_addr, 0, 25);

    Console.WriteLine(str);

    Console.Read();
         }
    }
}

 

调试中出现过的Bug

.Program::GetUser”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

添加属性:EntryPoint = "GetUser", CallingConvention = CallingConvention.Cdecl

结果:

 

(3)C++传入、传出带参数结构体

.h文件
#define TESTCPPDLL_API __declspec(dllexport)
struct Vector3

{

    float X, Y, Z;

};

EXTERN_C TESTCPPDLL_API void __stdcall SendStructFromCSToCPP(Vector3 vector);

 

.cpp文件
TESTCPPDLL_API void __stdcall SendStructFromCSToCPP(Vector3 vector)

{
    vector.X = vector.X + 10;
    cout << "got vector3 in cpp,x:";

    cout << vector.X+10;

    cout << ",Y:";

    cout << vector.Y;

    cout << ",Z:";

    cout << vector.Z;

}

 

.CS文件
[StructLayout(LayoutKind.Sequential)]

            struct Vector3
            {

                public float X, Y, Z;

            }



            [DllImport(@"C:\Users\wdy\Documents\visual studio 2013\Projects\TestCPPDLL\x64\Debug\TestCPPDLL.dll", EntryPoint = "SendStructFromCSToCPP")]

            extern static void SendStructFromCSToCPP(Vector3 vector);
Vector3 vector = new Vector3() { X = 10, Y = 20, Z = 30 };

                //将vector传递给C++并在C++中输出

                SendStructFromCSToCPP(vector);

 

结果

 

posted @ 2017-12-04 14:44  ye_ming  阅读(15339)  评论(0编辑  收藏  举报