顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

2017年6月1日 星期四

Passing struct pointer from C++ dll to C#


#include <stdio.h>
#include <Windows.h>
struct Name
{
char FirstName[100];
char LastName[100];
char *Array[3];
};
extern "C" __declspec(dllexport) void __cdecl GetName(struct Name *name)
{
strncpy_s(name->FirstName, "FirstName", sizeof(name->FirstName));
name->Array[0] = "Foo 0";
name->Array[1] = "Foo 1";
name->Array[2] = "Foo 2";
}
extern "C" __declspec(dllexport) void __cdecl Hello()
{
printf("Hello\n");
}
using System;
using System.Runtime.InteropServices;
namespace TestApp
{
class Program
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Name
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string LastName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public string[] Array;
};
[DllImport("TestDll.dll")]
public static extern void GetName(ref Name name);
[DllImport("TestDll.dll")]
public static extern void Hello();
static void Main(string[] args)
{
Hello();
var name = new Name();
GetName(ref name);
Console.WriteLine(name.FirstName);
foreach (var s in name.Array)
Console.WriteLine(s);
}
}
}

2017年5月25日 星期四

Passing string between C# and C++ dll

From C# to C++ dll

C++
void foo(const char *str)
{
    // do something with str
}
C#
[DllImport("...", CallingConvention = CallingConvention.Cdecl)
static extern void foo(string str);

....

foo("bar");
In the other direction you would typically expect the caller to allocate the buffer, into which the callee can write:
C++
void foo(char *str, int len)
{
    // write no more than len characters into str
}
C#
[DllImport("...", CallingConvention = CallingConvention.Cdecl)
static extern void foo(StringBuilder str, int len);

....

StringBuilder sb = new StringBuilder(10);
foo(sb, sb.Capacity);



From C++ dll to C#
C++ 裡面:
TCHAR g_awcMessage[] = L"Hello中文"; char g_aszMessage[] = "Hello中文";
extern "C" __declspec(dllexport) TCHAR* __stdcall GetHelloL() {   return g_awcMessage;  }
extern "C" __declspec(dllexport) CHAR* __stdcall GetHello() {   return g_aszMessage; }
extern "C" __declspec(dllexport) int __stdcall GetInt() {   return 100; }
C# 裡面:
[DllImport("gpDll.dll")] public static extern IntPtr GetHello();
[DllImport("gpDll.dll")] public static extern IntPtr GetHelloL();
[DllImport("gpDll.dll")] public static extern int GetInt();
private void button1_Click(object sender, EventArgs e) {             // Not support in CF             //Marshal.PtrToStringAnsi             //Marshal.PtrToStringAuto
            // Multibytes 會變成亂碼             string str =  Marshal.PtrToStringUni(GetHello());
            // Wide Character 顯示正常             string str = Marshal.PtrToStringAnsi(GetHello());
            // Wide Character 顯示正常             string strL = Marshal.PtrToStringUni(GetHelloL());
            int n = GetInt(); }