13,009
回編集
722行目: | 722行目: | ||
// SampleDLL.h | // SampleDLL.h | ||
void __stdcall SampleFunc01( | void __stdcall SampleFunc01(SampleStruct1 Structure) | ||
void __stdcall SampleFunc02( | void __stdcall SampleFunc02(SampleStruct2 *pStructure) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
735行目: | 735行目: | ||
typedef struct tagSampleStruct | typedef struct tagSampleStruct | ||
{ | { | ||
int index; | int index; | ||
char name[128]; | char name[128]; | ||
int data[50]; | int data[50]; | ||
} | } SampleStruct1, *pSampleStruct; | ||
typedef struct tagSampleStruct2 | typedef struct tagSampleStruct2 | ||
{ | { | ||
int length; | int length; | ||
double *data; | double *data; | ||
} SampleStruct2, *pSampleStruct2; | } SampleStruct2, *pSampleStruct2; | ||
void __stdcall SampleFunc01( | void __stdcall SampleFunc01(SampleStruct1 st) | ||
{ | { | ||
printf("--<SampleDll: | printf("--<SampleDll:SampleFunc01>--\r\n"); | ||
printf("index = %d\r\n", st.index); | printf("index = %d\r\n", st.index); | ||
printf("name = %s\r\n", st.name); | printf("name = %s\r\n", st.name); | ||
757行目: | 757行目: | ||
void __stdcall SampleFunc02(SampleStruct2 *pStructure) | void __stdcall SampleFunc02(SampleStruct2 *pStructure) | ||
{ | { | ||
printf("--<SampleDll:SampleFunc02>--\r\n"); | |||
printf("--<SampleDll: | |||
memset(pStructure, 0, sizeof(SampleStruct2)); | memset(pStructure, 0, sizeof(SampleStruct2)); | ||
pStructure->length = 10; | |||
pStructure->data = | pStructure->length = 10; | ||
double dAryData[pStructure->length] = {0.0f}; | |||
pStructure->data = dAryData; | |||
for(int i = 0; i < pStructure->length; i++) | for(int i = 0; i < pStructure->length; i++) | ||
{ | { | ||
dAryData[i] = (i + 1) / 10.0f; | |||
} | } | ||
printf("------------------------\r\n"); | printf("------------------------\r\n"); | ||
} | } | ||
801行目: | 805行目: | ||
/// </summary> | /// </summary> | ||
/// <param name="st">DLL 側に渡す構造体を指定します</param> | /// <param name="st">DLL 側に渡す構造体を指定します</param> | ||
[DllImport("SampleDLL.dll")] | [DllImport("SampleDLL.dll", EntryPoint = "SampleFunc01", CallingConvention = CallingConvention.Cdecl)] | ||
private static extern void | private static extern void _SampleFunc01(SampleStruct1 st); | ||
/// <summary> | /// <summary> | ||
808行目: | 812行目: | ||
/// </summary> | /// </summary> | ||
/// <param name="pst">受け渡す構造体の先頭アドレスを示すポインタを指定する</param> | /// <param name="pst">受け渡す構造体の先頭アドレスを示すポインタを指定する</param> | ||
[DllImport("SampleDLL.dll")] | [DllImport("SampleDLL.dll", EntryPoint = "SampleFunc02", CallingConvention = CallingConvention.Cdecl)] | ||
private static extern void | private static extern void _SampleFunc02(IntPtr pst); | ||
/// <summary> | /// <summary> | ||
815行目: | 819行目: | ||
/// LayoutKind.Sequentialを指定することで、C/C++同様、変数の宣言順通りにメモリに配置されるようになる | /// LayoutKind.Sequentialを指定することで、C/C++同様、変数の宣言順通りにメモリに配置されるようになる | ||
/// </summary> | /// </summary> | ||
[StructLayout(LayoutKind.Sequential)] | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | ||
private struct | private struct SampleStruct1 | ||
{ | { | ||
/// <summary> | /// <summary> | ||
850行目: | 854行目: | ||
static void Main(string[] args) | static void Main(string[] args) | ||
{ | { | ||
var | SampleFunc01(); | ||
SampleFunc02(); | |||
Console.ReadKey(); | |||
} | |||
private static void SampleFunc01() | |||
{ | |||
var structure = new SampleStruct1() | |||
{ | { | ||
index = 4, | index = 4, | ||
857行目: | 869行目: | ||
}; | }; | ||
structure.data[0] = 11; | |||
structure.data[1] = 22; | |||
structure.data[2] = 33; | |||
_SampleFunc01(structure); | |||
} | |||
private static void SampleFunc02() | |||
{ | |||
// SampleStruct2構造体のサイズを取得する | // SampleStruct2構造体のサイズを取得する | ||
// | // 指定サイズ分だけメモリ領域を確保して、その先頭アドレスをstructure1に格納する | ||
var | var structure1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SampleStruct2))); | ||
try | try | ||
{ | { | ||
SampleFunc02( | // C++ DLLのSampleFunc02関数の実行 | ||
// | SampleFunc02(structure1); | ||
var | |||
for (int i = 0; i < | // 受け取ったstructure1からSampleStruct2構造体の情報に構築し直す | ||
var structure2 = (SampleStruct2)Marshal.PtrToStructure(structure1, typeof(SampleStruct2)); | |||
for (int i = 0; i < structure2.length; i++) | |||
{ | { | ||
// IntPtr型からdouble型の数値を取得するときは、一度Int64型に変換して、これをBitConverter.Int64BitsToDoubleメソッドでdouble型に変換する | // IntPtr型からdouble型の数値を取得するときは、一度Int64型に変換して、これをBitConverter.Int64BitsToDoubleメソッドでdouble型に変換する | ||
var v = Marshal.ReadInt64( | var v = Marshal.ReadInt64(structure2.data, i * sizeof(double)); | ||
Console.WriteLine("data[{0}] = {1}", i, BitConverter.Int64BitsToDouble(v)); | Console.WriteLine("data[{0}] = {1}", i, BitConverter.Int64BitsToDouble(v)); | ||
} | } | ||
884行目: | 902行目: | ||
{ | { | ||
// 必ずメモリを解放する | // 必ずメモリを解放する | ||
Marshal.FreeHGlobal( | Marshal.FreeHGlobal(structure1); | ||
} | } | ||
} | } | ||
} | } |