Skip to content

Instantly share code, notes, and snippets.

@hmuronaka
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hmuronaka/9fed248b16eecf471cba to your computer and use it in GitHub Desktop.
Save hmuronaka/9fed248b16eecf471cba to your computer and use it in GitHub Desktop.
C#でレガシーな事をする方向けのまとめ ref: http://qiita.com/hmuronaka/items/619f8889e36c7b5db92d
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Header
{
ushort len;
byte firstAddress;
byte secondAddress;
byte sourceAddress;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct A
{
public int a;
public byte b;
public static readonly int len;
static A()
{
len = Marshal.SizeOf(typeof(A)); => 5
}
}
struct A
{
int a;
int b;
}
void foo()
{
A a = new A() { a=10,b=20 };
A b = a; // オブジェクトの参照ではなく値のコピーが行われる。
b.a = 30; => a.a==10 b.a==30
}
void init()
{
Func<int,int,int> addDelegate = delegate(int a,int b) {
return a + b;
}
int sum = foo(1,2, addDelegate);
}
int foo(int a, int b, Func<int,int,int> operation) {
return operation(a,b);
}
delegate void fucn();
func myFunc = null;
void foo() {
if( myFunc != null ) {
myFunc();
}
}
void otherThreadMain()
{
items...
listView.Invoke((MethodInvoker)delegate()
{
listView.Clear();
listView.AddRange(items);
},null);
}
using System.Runtime.InteropServices;
[System.Runtime.InteropServices.DllImport("MyDll.dll" ,CallingConvention=CallingConvention.ThisCall, EntryPoint = "? get@CMyFunc@@QAEHHH@Z")]
extern Int32 get(Int32 a, Int32 b);
class CUDPSocket;
class DLLDECLAR CMyTest
{
private:
CUDPSocket* mSocket;
public:
CMyTest(void);
virtual ~ CMyTest(void);
public:
INT get(INT a, INT b);
};
// new 用
DLLDECLAR CMyTest* newMyTest();
// delete用
DLLDECLAR void releaseMyTest(CMyTest* obj);
namespace XXX
{
public class MyTest : IDisposable
{
// EntryPointはDependency Walkerなどで調べる...
[System.Runtime.InteropServices.DllImport("MyTestDll.dll", EntryPoint = "?newMyTest@@YAPAVCMyTest@@XZ")]
static extern IntPtr newMyTest();
[System.Runtime.InteropServices.DllImport("MyTest.dll", EntryPoint = "?releaseMyTest@@YAXPAVCMyTest@@@Z")]
static extern void deleteMyTest(IntPtr obj);
// メソッドは呼び出し規約を明示する必要がある。
[System.Runtime.InteropServices.DllImport("MyTestDll.dll" ,CallingConvention=CallingConvention.ThisCall, EntryPoint = "? get@CMyTest@@QAEHHH@Z")]
static extern Int32 get(IntPtr obj, Int32 a, Int32 b);
[System.Runtime.InteropServices.DllImport("MyTest.dll", EntryPoint="?addDll@@YAHHH@Z")]
static extern Int32 addDll(Int32 a, Int32 b);
IntPtr mBody;
public MyTest()
{
this.mBody = newMyTest();
}
public void Dispose()
{
deleteMyTest(this.mBody);
}
public Int32 Get(Int32 a, Int32 b)
{
return get(this.mBody, a, b);
}
public static Int32 Add(Int32 a, Int32 b)
{
return addDll(a, b);
}
}
}
ListBox listBox1;
public void onReceiveAlive(Object sender, InetEvent evt)
{
// 他スレッドから呼び出された場合.
if (listBox1.InvokeRequired)
{
listBox1.Invoke(new Action<Object, InetEvent>(onReceiveAlive),
new Object[] { sender, evt });
return;
}
// 通常の処理.
listBox1.Items.Insert(0, "test");
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct B
{
public byte a;
public A b;
public static readonly int len;
static B()
{
len = Marshal.SizeOf(typeof(B)); => 6 (A.len + sizeof(b))
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct A
{
public int a;
public byte[] b;
public static readonly int len;
static A()
{
len = Marshal.SizeOf(typeof(A)); => 8
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct B
{
public byte a;
public A b;
public static readonly int len;
static B()
{
len = Marshal.SizeOf(typeof(B)); => 9 (A.len + sizeof(b))
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct A
{
public int a;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] b;
public static readonly int len;
static A()
{
len = Marshal.SizeOf(typeof(A)); => 6
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct B
{
public byte a;
public A b;
public static readonly int len;
static B()
{
len = Marshal.SizeOf(typeof(B)); => 7 (A.len + sizeof(a))
}
}
struct AAA
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
public byte[] test;
}
struct AAA
{
public byte[] test;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct A
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public int a; => MarshalAsを指定して非配列はNG. Marshal系のメソッドを利用するとException発生.
public static readonly int len;
static A()
{
len = Marshal.SizeOf(typeof(A));
}
}
public struct A
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] a;
public static readonly int len;
static A()
{
len = Marshal.SizeOf(typeof(A));
}
}
void foo()
{
A a = new A();
a.a = new byte[2]; => newの必要あり。サイズがSizeConstと一致の必要有
}
public static void byteToStruct<T>(byte[] buffer, int pos, int typeLen, out T result)
{
int endPos = pos + typeLen;
if (endPos > buffer.Length)
{
throw new Exception("サイズ不正[endPos," + endPos.ToString() + "][buflen," + buffer.Length.ToString() + "]");
}
T obj;
IntPtr ptr = Marshal.AllocHGlobal(typeLen);
try
{
Marshal.Copy(buffer, pos, ptr, typeLen);
obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
result = obj;
}
finally
{
if (IntPtr.Zero != ptr)
{
Marshal.FreeHGlobal(ptr);
}
}
}
public static void structToByte<T>(T obj, int typeLen, byte[] buffer, int pos)
{
int endPos = pos + typeLen;
if (endPos > buffer.Length)
{
throw new Exception("サイズ不正[endPos," + endPos.ToString() + "][buflen," + buffer.Length.ToString() + "]");
}
IntPtr ptr = Marshal.AllocHGlobal(typeLen);
try
{
Marshal.StructureToPtr(obj, ptr, false);
Marshal.Copy(ptr, buffer, pos, typeLen);
}
finally
{
if (IntPtr.Zero != ptr)
{
Marshal.FreeHGlobal(ptr);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment