-
-
Notifications
You must be signed in to change notification settings - Fork 133
Examples Part 2
-
00:10 - Passing Unicode strings from C# to unmanaged C++ ((host side)). Samples for arguments and for the return value.
-
05:21 - Passing complex types from C# to unmanaged C++ ((host side)). Samples for structures.
-
08:42 - Passing arrays from unmanaged C++ ((host side)) to C#.
-
11:33 - By the way, How to debug at runtime both managed + unmanaged environments. ~(.NET Clr & native unmanaged C++)
-
12:27 - Passing multidimensional arrays from C++ ((host side)) to C#.
-
14:22 - Passing Unicode strings from C++ to C# ((host side)).
-
16:23 - Passing complex types from C++ to C# ((host side)). Samples for structures.
-
20:50 - An alternative. Native C/C++ structures without declaration. Manual accessing at runtime.
-
22:47 - Passing arrays to C# from Java ((host side)). Do it anywhere.
-
@ 24:34 how it can be implemented without information about size. Think different -_*
C++
const TCHAR* pemodule = _T("D:\\Samples\\PEClr\\bin\\PEClr.dll");
HMODULE lib = LoadLibrary(pemodule);
typedef void(__cdecl *alloc)();
typedef void(__cdecl *free)();
((alloc)GetProcAddress(lib, "alloc"))();
// -- getString()
typedef const TCHAR* (__cdecl *getString)();
auto pGetString = (getString)GetProcAddress(lib, "getString");
const TCHAR* msg = pGetString();
// -- via out/ref
typedef void (__cdecl *getStringArgs)(const TCHAR** );
auto pGetStringArgs = (getStringArgs)GetProcAddress(lib, "getStringArgs");
const TCHAR* msgArg = nullptr;
pGetStringArgs(&msgArg);
// TVer
struct TVer
{
int major;
int minor;
int patch;
};
typedef const TVer* (__cdecl *getTVer)();
auto pGetTVer = (getTVer)GetProcAddress(lib, "getTVer");
const TVer* ver = pGetTVer();
// -- setArray
typedef bool(__cdecl *setArray)(const int*, int size);
auto pSetArray = (setArray)GetProcAddress(lib, "setArray");
int data[] = { 0x0D, 0x0E, 0x0F, 0x3F };
pSetArray(data, 4);
int datam[2][2] = { { 0x0D, 0x0E }, { 0x0F, 0x3F } };
pSetArray(*datam, 4);
((free)GetProcAddress(lib, "free"))();
FreeLibrary(lib);
C#
public static class Sample2
{
private static UnmanagedString msg;
private static UnmanagedStructure data;
private struct TVer
{
public int major;
public int minor;
public int patch;
public TVer(int major, int minor, int patch)
{
this.major = major;
this.minor = minor;
this.patch = patch;
}
}
[DllExport]
public static IntPtr getString()
{
return msg;
}
[DllExport]
public static void getStringArgs(out IntPtr ptr)
{
ptr = msg;
}
[DllExport]
public static void printArray(IntPtr ptr)
{
int _r(IntPtr src, int ofs)
{
return Marshal.ReadInt32(ptr, ofs);
};
string _get(IntPtr _ptr, int zzz)
{
string ret = String.Empty;
int ofs = Marshal.SizeOf(typeof(Int32));
int num, i = 0;
while((num = _r(ptr, ofs * i++)) != zzz) {
ret += $"\n-> {num}";
}
return ret;
};
MessageBox.Show(_get(ptr, 7), "-_*");
}
[DllExport]
public static bool setArray(IntPtr ptr, int size)
{
// I'll add more features soon (I hope) for work with different arrays in Conari via pointers !
// stay in touch :) github.com/3F
int[] data = new int[size];
Marshal.Copy(ptr, data, 0, data.Length);
// TODO: ....
return data?.Length > 0;
}
[DllExport]
public static IntPtr getTVer()
{
return data;
}
[DllExport]
public static void alloc()
{
msg = new UnmanagedString("Hello ! this is a unicode characters from .NET clr", UnmanagedString.SType.Unicode);
data = new UnmanagedStructure(new TVer(2, 7, 1));
}
[DllExport]
public static void free()
{
msg?.Dispose();
data?.Dispose();
}
}
C++
EXAPI const TCHAR* getString()
{
return _T("Hello from unmanaged C++");
}
// what about complex types ?
struct MyStruct
{
int x;
int y;
int z;
};
EXAPI const MyStruct* allocStruct(int x, int y, int z)
{
return new MyStruct{ x, y, z };
}
EXAPI void freeStruct(const MyStruct* obj)
{
delete obj;
}
C#
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
public int x, y, z;
}
...
using(var l = new ConariL(@"D:\Samples\PENative\x64\Debug\DllNative.dll"))
{
var d = l.DLR; // or with details via bind<> .. etc.
string msg = d.getString<WCharPtr>();
IntPtr ptr = d.allocStruct<IntPtr>(7, 4, 12);
l.BeforeUnload += (object sender, DataArgs<Link> e) => {
d.freeStruct();
};
var us = new UnmanagedStructure(ptr, typeof(MyStruct));
var g = (MyStruct)us.Managed;
unchecked {
long v = g.x + g.y - g.z;
}
// or like
var z = ptr.Native()
.align<int>(2)
.t<int>("z")
.Raw.Type.DLR.z;
// ~ z = ptr.Native().field<int>(3);
// etc.
}
- Part-1. Managed & Unmanaged; PInvoke. C++ ❤ C#.
- Conari.
- JNA.
- You can also use my old an explanation, for example, from here:
...
Except where otherwise noted, wiki content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. (CC BY-SA 4.0).
🗎
- 🗎 Home
- 🗎 Quick start (+📹)
- 🗎 .Net Core
- 🗎 Export
- 🗎 Pre-processing
- 🗎 Conari support
- 🗎 ILMerge support
- 🗎 [x]AssemblyResolve
- 🗎 Post-processing
- 🗎 Examples
- 🗎 C++ ❤ C# (+📹)
- 🗎 String & struct (+📹)
- 🗊 Complete Examples
🗔
📂
- 📢 Q/A