ホーム › System.Com › SAFEARRAY
SAFEARRAY
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 |
|---|---|---|---|---|---|
| cDims | WORD | 2 | +0 | +0 | 配列の次元数。 |
| fFeatures | ADVANCED_FEATURE_FLAGS | 2 | +2 | +2 | 配列の特性を示すフラグ(FADF_系)。要素型や所有関係を表す。 |
| cbElements | DWORD | 4 | +4 | +4 | 1要素のバイトサイズ。 |
| cLocks | DWORD | 4 | +8 | +8 | 現在のロック回数。SafeArrayLockで増減する。 |
| pvData | void* | 8/4 | +16 | +12 | 配列要素データの先頭へのポインタ。 |
| rgsabound | SAFEARRAYBOUND | 8 | +24 | +16 | 各次元の境界情報(SAFEARRAYBOUND)配列。 |
各言語での定義
#include <windows.h>
// SAFEARRAYBOUND (x64 8 / x86 8 バイト)
typedef struct SAFEARRAYBOUND {
DWORD cElements;
INT lLbound;
} SAFEARRAYBOUND;
// SAFEARRAY (x64 32 / x86 24 バイト)
typedef struct SAFEARRAY {
WORD cDims;
ADVANCED_FEATURE_FLAGS fFeatures;
DWORD cbElements;
DWORD cLocks;
void* pvData;
SAFEARRAYBOUND rgsabound[1];
} SAFEARRAY;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SAFEARRAYBOUND
{
public uint cElements;
public int lLbound;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SAFEARRAY
{
public ushort cDims;
public ushort fFeatures;
public uint cbElements;
public uint cLocks;
public IntPtr pvData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public SAFEARRAYBOUND[] rgsabound;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure SAFEARRAYBOUND
Public cElements As UInteger
Public lLbound As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure SAFEARRAY
Public cDims As UShort
Public fFeatures As UShort
Public cbElements As UInteger
Public cLocks As UInteger
Public pvData As IntPtr
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> Public rgsabound() As SAFEARRAYBOUND
End Structureimport ctypes
from ctypes import wintypes
class SAFEARRAYBOUND(ctypes.Structure):
_fields_ = [
("cElements", wintypes.DWORD),
("lLbound", ctypes.c_int),
]
class SAFEARRAY(ctypes.Structure):
_fields_ = [
("cDims", ctypes.c_ushort),
("fFeatures", ctypes.c_ushort),
("cbElements", wintypes.DWORD),
("cLocks", wintypes.DWORD),
("pvData", ctypes.c_void_p),
("rgsabound", SAFEARRAYBOUND * 1),
]#[repr(C)]
pub struct SAFEARRAYBOUND {
pub cElements: u32,
pub lLbound: i32,
}
#[repr(C)]
pub struct SAFEARRAY {
pub cDims: u16,
pub fFeatures: u16,
pub cbElements: u32,
pub cLocks: u32,
pub pvData: *mut core::ffi::c_void,
pub rgsabound: [SAFEARRAYBOUND; 1],
}import "golang.org/x/sys/windows"
type SAFEARRAYBOUND struct {
cElements uint32
lLbound int32
}
type SAFEARRAY struct {
cDims uint16
fFeatures uint16
cbElements uint32
cLocks uint32
pvData uintptr
rgsabound [1]SAFEARRAYBOUND
}type
SAFEARRAYBOUND = record
cElements: DWORD;
lLbound: Integer;
end;
SAFEARRAY = record
cDims: Word;
fFeatures: Word;
cbElements: DWORD;
cLocks: DWORD;
pvData: Pointer;
rgsabound: array[0..0] of SAFEARRAYBOUND;
end;const SAFEARRAYBOUND = extern struct {
cElements: u32,
lLbound: i32,
};
const SAFEARRAY = extern struct {
cDims: u16,
fFeatures: u16,
cbElements: u32,
cLocks: u32,
pvData: ?*anyopaque,
rgsabound: [1]SAFEARRAYBOUND,
};type
SAFEARRAYBOUND {.bycopy.} = object
cElements: uint32
lLbound: int32
SAFEARRAY {.bycopy.} = object
cDims: uint16
fFeatures: uint16
cbElements: uint32
cLocks: uint32
pvData: pointer
rgsabound: array[1, SAFEARRAYBOUND]struct SAFEARRAYBOUND
{
uint cElements;
int lLbound;
}
struct SAFEARRAY
{
ushort cDims;
ushort fFeatures;
uint cbElements;
uint cLocks;
void* pvData;
SAFEARRAYBOUND[1] rgsabound;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; SAFEARRAY サイズ: 24 バイト(x86)
dim st, 6 ; 4byte整数×6(構造体サイズ 24 / 4 切り上げ)
; cDims : WORD (+0, 2byte) wpoke st,0,値 / 値 = wpeek(st,0)
; fFeatures : ADVANCED_FEATURE_FLAGS (+2, 2byte) wpoke st,2,値 / 値 = wpeek(st,2)
; cbElements : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; cLocks : DWORD (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; pvData : void* (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; rgsabound : SAFEARRAYBOUND (+16, 8byte) varptr(st)+16 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; SAFEARRAY サイズ: 32 バイト(x64)
dim st, 8 ; 4byte整数×8(構造体サイズ 32 / 4 切り上げ)
; cDims : WORD (+0, 2byte) wpoke st,0,値 / 値 = wpeek(st,0)
; fFeatures : ADVANCED_FEATURE_FLAGS (+2, 2byte) wpoke st,2,値 / 値 = wpeek(st,2)
; cbElements : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; cLocks : DWORD (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; pvData : void* (+16, 8byte) qpoke st,16,値 / qpeek(st,16) ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; rgsabound : SAFEARRAYBOUND (+24, 8byte) varptr(st)+24 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global SAFEARRAYBOUND
#field int cElements
#field int lLbound
#endstruct
#defstruct global SAFEARRAY
#field short cDims
#field short fFeatures
#field int cbElements
#field int cLocks
#field intptr pvData
#field SAFEARRAYBOUND rgsabound 1
#endstruct
stdim st, SAFEARRAY ; NSTRUCT 変数を確保
st->cDims = 100
mes "cDims=" + st->cDims