関連記事
- 【#CSharp】C#が2025年「プログラミング言語オブ・ザ・イヤー」獲得 【2026年01月16日(金)】
- 【memory leak】メモリーリーク発生...ドロドロドロ 【2025年10月27日(月)】
- う~~忙しい!あ~~忙しい!! 【2025年09月24日(水)】
- なんと!今週の土曜日も仕事してますた.来週の土曜日も仕事臭い.TCPソケット通信をゴリゴリ書いてる 【2025年08月30日(土)】
- 【ChatGPT o4】祝日なのに仕事ーバテすぎー今夜こそ絶命だーモルモルモル 【2025年03月20日(木)】
ブログ側から記事を移動させました…
構造体配列の先頭ポインタを取る方法って,どう書くんだっけ?
の話
かなぁ~り,めんどくさい手段とれば,取れそうな感じ
まずはC++のDLL側ソース(さっきのソース,バグってます(ww)
//ヘッダ側(.h)
#ifndef __FUNC_TESTFUNC_H__
#define __FUNC_TESTFUNC_H__
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
float wx;
float wy;
float wz;
int x;
int y;
} POINT_LCTOWL, *PPOINT_LCTOWL;
int WINAPI get_PointInfoArray(PPOINT_LCTOWL &aryPtr, int &arySize); //構造体配列の先頭ポインタと配列長を取得
#ifdef __cplusplus
}
#endif
#endif //__FUNC_CARIBXML_H__
//実装側(.cpp)
#include "StdAfx.h"
#include "TestFunc.h"
POINT_LCTOWL g_PointInfoArray[10];
extern "C" int WINAPI get_PointInfoArray(PPOINT_LCTOWL &aryPtr, int &arySize)
{
g_PointInfoArray[0].wx = 1;
g_PointInfoArray[0].wy = 2;
g_PointInfoArray[0].wz = 3;
g_PointInfoArray[1].wx = 11;
g_PointInfoArray[1].wy = 12;
g_PointInfoArray[1].wz = 13;
g_PointInfoArray[2].wx = 21;
g_PointInfoArray[2].wy = 22;
g_PointInfoArray[2].wz = 23;
aryPtr = &g_PointInfoArray[0];
arySize = 10;
return 0;
}
んで,C#側
これがウルトラ面倒だわ
namespace arrydllTestOya
{
[StructLayout(LayoutKind.Sequential)]
public struct POINT_LCTOWL{
public float wx;
public float wy;
public float wz;
public int x;
public int y;
}
public partial class Form1 : Form
{
[DllImport(“arrayDllTest.dll”)]
public static extern int get_PointInfoArray(out IntPtr ary, out int aryCount);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
POINT_LCTOWL[] a;
IntPtr b;
int ac;
get_PointInfoArray(out b, out ac);
a = new POINT_LCTOWL[ac];
int size = Marshal.SizeOf(typeof(POINT_LCTOWL));
for (int i = 0; i < ac; i++) {
//ポインタを、sizeずつずらしていく。
IntPtr current = new IntPtr(b.ToInt64() + (size * i));
//ポインタから構造体に変換して配列に格納。
a[i] = (POINT_LCTOWL)Marshal.PtrToStructure(
current, typeof(POINT_LCTOWL));
}
string st;
st = a[0].wx.ToString() + "," + a[0].wy.ToString() + "," + a[0].wz.ToString();
listBox1.Items.Add(st);
st = a[1].wx.ToString() + "," + a[1].wy.ToString() + "," + a[1].wz.ToString();
listBox1.Items.Add(st);
st = a[2].wx.ToString() + "," + a[2].wy.ToString() + "," + a[2].wz.ToString();
listBox1.Items.Add(st);
GC.Collect();
}
}
}
[/csharp]
-
1.DLL側から,構造体配列の先頭ポインタをIntPtr型で受取り
2.構造体配列のインスタンスを生成
3.各要素ごとにIntPtrの値+構造体サイズのオフセット値を計算して
4.3で計算した値をMarshal.PtrToStructure()にて,配列要素に叩き込む
んで,問題が…
GC(ガーベジコレクション)が走ったら,DLL(アンマネージ)内のメモリ,勝手に解放しないか??
ちょいと心配…
-
追記
-
なんとなく,だけど,Marshal.PtrToStructure()って,ポインタの書き換えとか,やっているんじゃなくて
IntPtrのメモリ位置から指定サイズ分のブロック切り出して,マーシャリング
んで,配列の要素に,そのブロック実体をコピーしているような気がしてきた
これなら,GCの解放動作とか,問題にはならないけど…
でも毎度毎度,コピーするってのもなんだかなぁ(速度的にナニだし)
DLL内部のメモリブロック,ポインタから直接参照するって方法,ないものかねぇ~
もう少し突っ込んでテストしてみるけど
基本,これで,DLL内の構造体配列は,参照できた,ということで♥
参考 : WTSEnumerateSessionsとP/Invoke@ぬるり。さんのページ

コメント
【#衆議院選挙2026 】自民 316議席獲得 単独で3分の2超 中道は49議席
【#衆議院選挙2026 】自民単独で過半数大きく上回り300議席に達する可能性
【BW55T】UPSが死んだ...ドロドロドロ😭これは人類滅亡間違いなし!なので発注(爆
広島カープの羽月隆太郎容疑者、「ゾンビたばこ」使用の疑いで逮捕
【#総選挙】衆議院選挙 きょう公示 12日間の選挙戦へ
青森 スノーモービル乗るため入山の約10人と連絡取れず 遭難か
【#不発弾】宮崎市中心部の不発弾 17日に処理 避難指示や交通規制予定(26/1/17)
【総選挙】立民 公明 衆院選に向け新党結成で合意(26/1/15)
【大雪】大雪と雷及び突風に関する全般気象情報 第3号(26/1/1)