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);

 

結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM