Win32 API 日本語リファレンス
ホームStorage.Cabinets › FCICreate

FCICreate

関数
ファイル圧縮インターフェイス(FCI)のコンテキストを生成する。
DLLCabinet.dll呼出規約cdecl

シグネチャ

// Cabinet.dll
#include <windows.h>

void* FCICreate(
    ERF* perf,
    PFNFCIFILEPLACED pfnfcifp,
    PFNFCIALLOC pfna,
    PFNFCIFREE pfnf,
    PFNFCIOPEN pfnopen,
    PFNFCIREAD pfnread,
    PFNFCIWRITE pfnwrite,
    PFNFCICLOSE pfnclose,
    PFNFCISEEK pfnseek,
    PFNFCIDELETE pfndelete,
    PFNFCIGETTEMPFILE pfnfcigtf,
    CCAB* pccab,
    void* pv   // optional
);

パラメーター

名前方向説明
perfERF*inエラー情報を受け取るERF構造体へのポインタ。FCI操作中の発生エラーを記録する。
pfnfcifpPFNFCIFILEPLACEDinファイルがキャビネットへ配置された際に呼ばれるコールバック関数ポインタ。
pfnaPFNFCIALLOCinメモリ割り当て用コールバック関数ポインタ。FCI内部のメモリ確保に使われる。
pfnfPFNFCIFREEinメモリ解放用コールバック関数ポインタ。pfnaで確保したメモリの解放に使われる。
pfnopenPFNFCIOPENinファイルを開くためのコールバック関数ポインタ。FCIがI/O時に使用する。
pfnreadPFNFCIREADinファイル読み取り用コールバック関数ポインタ。
pfnwritePFNFCIWRITEinファイル書き込み用コールバック関数ポインタ。
pfnclosePFNFCICLOSEinファイルを閉じるためのコールバック関数ポインタ。
pfnseekPFNFCISEEKinファイルシーク用コールバック関数ポインタ。ファイル位置の移動に使われる。
pfndeletePFNFCIDELETEinファイル削除用コールバック関数ポインタ。一時ファイル等の削除に使われる。
pfnfcigtfPFNFCIGETTEMPFILEin一時ファイル名取得用コールバック関数ポインタ。FCIが作業用一時ファイルを得るために呼ぶ。
pccabCCAB*inキャビネットのサイズや格納パス等の設定を保持するCCAB構造体へのポインタ。
pvvoid*inoptionalコールバックへ引き渡されるアプリケーション定義のコンテキストポインタ。NULL可。

戻り値の型: void*

各言語での呼び出し定義

// Cabinet.dll
#include <windows.h>

void* FCICreate(
    ERF* perf,
    PFNFCIFILEPLACED pfnfcifp,
    PFNFCIALLOC pfna,
    PFNFCIFREE pfnf,
    PFNFCIOPEN pfnopen,
    PFNFCIREAD pfnread,
    PFNFCIWRITE pfnwrite,
    PFNFCICLOSE pfnclose,
    PFNFCISEEK pfnseek,
    PFNFCIDELETE pfndelete,
    PFNFCIGETTEMPFILE pfnfcigtf,
    CCAB* pccab,
    void* pv   // optional
);
[DllImport("Cabinet.dll", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr FCICreate(
    IntPtr perf,   // ERF*
    IntPtr pfnfcifp,   // PFNFCIFILEPLACED
    IntPtr pfna,   // PFNFCIALLOC
    IntPtr pfnf,   // PFNFCIFREE
    IntPtr pfnopen,   // PFNFCIOPEN
    IntPtr pfnread,   // PFNFCIREAD
    IntPtr pfnwrite,   // PFNFCIWRITE
    IntPtr pfnclose,   // PFNFCICLOSE
    IntPtr pfnseek,   // PFNFCISEEK
    IntPtr pfndelete,   // PFNFCIDELETE
    IntPtr pfnfcigtf,   // PFNFCIGETTEMPFILE
    IntPtr pccab,   // CCAB*
    IntPtr pv   // void* optional
);
<DllImport("Cabinet.dll", ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function FCICreate(
    perf As IntPtr,   ' ERF*
    pfnfcifp As IntPtr,   ' PFNFCIFILEPLACED
    pfna As IntPtr,   ' PFNFCIALLOC
    pfnf As IntPtr,   ' PFNFCIFREE
    pfnopen As IntPtr,   ' PFNFCIOPEN
    pfnread As IntPtr,   ' PFNFCIREAD
    pfnwrite As IntPtr,   ' PFNFCIWRITE
    pfnclose As IntPtr,   ' PFNFCICLOSE
    pfnseek As IntPtr,   ' PFNFCISEEK
    pfndelete As IntPtr,   ' PFNFCIDELETE
    pfnfcigtf As IntPtr,   ' PFNFCIGETTEMPFILE
    pccab As IntPtr,   ' CCAB*
    pv As IntPtr   ' void* optional
) As IntPtr
End Function
' perf : ERF*
' pfnfcifp : PFNFCIFILEPLACED
' pfna : PFNFCIALLOC
' pfnf : PFNFCIFREE
' pfnopen : PFNFCIOPEN
' pfnread : PFNFCIREAD
' pfnwrite : PFNFCIWRITE
' pfnclose : PFNFCICLOSE
' pfnseek : PFNFCISEEK
' pfndelete : PFNFCIDELETE
' pfnfcigtf : PFNFCIGETTEMPFILE
' pccab : CCAB*
' pv : void* optional
Declare PtrSafe Function FCICreate Lib "cabinet" ( _
    ByVal perf As LongPtr, _
    ByVal pfnfcifp As LongPtr, _
    ByVal pfna As LongPtr, _
    ByVal pfnf As LongPtr, _
    ByVal pfnopen As LongPtr, _
    ByVal pfnread As LongPtr, _
    ByVal pfnwrite As LongPtr, _
    ByVal pfnclose As LongPtr, _
    ByVal pfnseek As LongPtr, _
    ByVal pfndelete As LongPtr, _
    ByVal pfnfcigtf As LongPtr, _
    ByVal pccab As LongPtr, _
    ByVal pv As LongPtr) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

FCICreate = ctypes.cdll.cabinet.FCICreate
FCICreate.restype = ctypes.c_void_p
FCICreate.argtypes = [
    ctypes.c_void_p,  # perf : ERF*
    ctypes.c_void_p,  # pfnfcifp : PFNFCIFILEPLACED
    ctypes.c_void_p,  # pfna : PFNFCIALLOC
    ctypes.c_void_p,  # pfnf : PFNFCIFREE
    ctypes.c_void_p,  # pfnopen : PFNFCIOPEN
    ctypes.c_void_p,  # pfnread : PFNFCIREAD
    ctypes.c_void_p,  # pfnwrite : PFNFCIWRITE
    ctypes.c_void_p,  # pfnclose : PFNFCICLOSE
    ctypes.c_void_p,  # pfnseek : PFNFCISEEK
    ctypes.c_void_p,  # pfndelete : PFNFCIDELETE
    ctypes.c_void_p,  # pfnfcigtf : PFNFCIGETTEMPFILE
    ctypes.c_void_p,  # pccab : CCAB*
    ctypes.POINTER(None),  # pv : void* optional
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('Cabinet.dll')
FCICreate = Fiddle::Function.new(
  lib['FCICreate'],
  [
    Fiddle::TYPE_VOIDP,  # perf : ERF*
    Fiddle::TYPE_VOIDP,  # pfnfcifp : PFNFCIFILEPLACED
    Fiddle::TYPE_VOIDP,  # pfna : PFNFCIALLOC
    Fiddle::TYPE_VOIDP,  # pfnf : PFNFCIFREE
    Fiddle::TYPE_VOIDP,  # pfnopen : PFNFCIOPEN
    Fiddle::TYPE_VOIDP,  # pfnread : PFNFCIREAD
    Fiddle::TYPE_VOIDP,  # pfnwrite : PFNFCIWRITE
    Fiddle::TYPE_VOIDP,  # pfnclose : PFNFCICLOSE
    Fiddle::TYPE_VOIDP,  # pfnseek : PFNFCISEEK
    Fiddle::TYPE_VOIDP,  # pfndelete : PFNFCIDELETE
    Fiddle::TYPE_VOIDP,  # pfnfcigtf : PFNFCIGETTEMPFILE
    Fiddle::TYPE_VOIDP,  # pccab : CCAB*
    Fiddle::TYPE_VOIDP,  # pv : void* optional
  ],
  Fiddle::TYPE_VOIDP, Fiddle::Function::CDECL)
#[link(name = "cabinet")]
extern "C" {
    fn FCICreate(
        perf: *mut ERF,  // ERF*
        pfnfcifp: *const core::ffi::c_void,  // PFNFCIFILEPLACED
        pfna: *const core::ffi::c_void,  // PFNFCIALLOC
        pfnf: *const core::ffi::c_void,  // PFNFCIFREE
        pfnopen: *const core::ffi::c_void,  // PFNFCIOPEN
        pfnread: *const core::ffi::c_void,  // PFNFCIREAD
        pfnwrite: *const core::ffi::c_void,  // PFNFCIWRITE
        pfnclose: *const core::ffi::c_void,  // PFNFCICLOSE
        pfnseek: *const core::ffi::c_void,  // PFNFCISEEK
        pfndelete: *const core::ffi::c_void,  // PFNFCIDELETE
        pfnfcigtf: *const core::ffi::c_void,  // PFNFCIGETTEMPFILE
        pccab: *mut CCAB,  // CCAB*
        pv: *mut ()  // void* optional
    ) -> *mut ();
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("Cabinet.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr FCICreate(IntPtr perf, IntPtr pfnfcifp, IntPtr pfna, IntPtr pfnf, IntPtr pfnopen, IntPtr pfnread, IntPtr pfnwrite, IntPtr pfnclose, IntPtr pfnseek, IntPtr pfndelete, IntPtr pfnfcigtf, IntPtr pccab, IntPtr pv);
"@
$api = Add-Type -MemberDefinition $sig -Name 'Cabinet_FCICreate' -Namespace Win32 -PassThru
# $api::FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
#uselib "Cabinet.dll"
#func global FCICreate "FCICreate" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; FCICreate varptr(perf), pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, varptr(pccab), pv   ; 戻り値は stat
; perf : ERF* -> "sptr"
; pfnfcifp : PFNFCIFILEPLACED -> "sptr"
; pfna : PFNFCIALLOC -> "sptr"
; pfnf : PFNFCIFREE -> "sptr"
; pfnopen : PFNFCIOPEN -> "sptr"
; pfnread : PFNFCIREAD -> "sptr"
; pfnwrite : PFNFCIWRITE -> "sptr"
; pfnclose : PFNFCICLOSE -> "sptr"
; pfnseek : PFNFCISEEK -> "sptr"
; pfndelete : PFNFCIDELETE -> "sptr"
; pfnfcigtf : PFNFCIGETTEMPFILE -> "sptr"
; pccab : CCAB* -> "sptr"
; pv : void* optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "Cabinet.dll"
#cfunc global FCICreate "FCICreate" var, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, var, sptr
; res = FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
; perf : ERF* -> "var"
; pfnfcifp : PFNFCIFILEPLACED -> "sptr"
; pfna : PFNFCIALLOC -> "sptr"
; pfnf : PFNFCIFREE -> "sptr"
; pfnopen : PFNFCIOPEN -> "sptr"
; pfnread : PFNFCIREAD -> "sptr"
; pfnwrite : PFNFCIWRITE -> "sptr"
; pfnclose : PFNFCICLOSE -> "sptr"
; pfnseek : PFNFCISEEK -> "sptr"
; pfndelete : PFNFCIDELETE -> "sptr"
; pfnfcigtf : PFNFCIGETTEMPFILE -> "sptr"
; pccab : CCAB* -> "var"
; pv : void* optional -> "sptr"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; void* FCICreate(ERF* perf, PFNFCIFILEPLACED pfnfcifp, PFNFCIALLOC pfna, PFNFCIFREE pfnf, PFNFCIOPEN pfnopen, PFNFCIREAD pfnread, PFNFCIWRITE pfnwrite, PFNFCICLOSE pfnclose, PFNFCISEEK pfnseek, PFNFCIDELETE pfndelete, PFNFCIGETTEMPFILE pfnfcigtf, CCAB* pccab, void* pv)
#uselib "Cabinet.dll"
#cfunc global FCICreate "FCICreate" var, intptr, intptr, intptr, intptr, intptr, intptr, intptr, intptr, intptr, intptr, var, intptr
; res = FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
; perf : ERF* -> "var"
; pfnfcifp : PFNFCIFILEPLACED -> "intptr"
; pfna : PFNFCIALLOC -> "intptr"
; pfnf : PFNFCIFREE -> "intptr"
; pfnopen : PFNFCIOPEN -> "intptr"
; pfnread : PFNFCIREAD -> "intptr"
; pfnwrite : PFNFCIWRITE -> "intptr"
; pfnclose : PFNFCICLOSE -> "intptr"
; pfnseek : PFNFCISEEK -> "intptr"
; pfndelete : PFNFCIDELETE -> "intptr"
; pfnfcigtf : PFNFCIGETTEMPFILE -> "intptr"
; pccab : CCAB* -> "var"
; pv : void* optional -> "intptr"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	cabinet = windows.NewLazySystemDLL("Cabinet.dll")
	procFCICreate = cabinet.NewProc("FCICreate")
)

// perf (ERF*), pfnfcifp (PFNFCIFILEPLACED), pfna (PFNFCIALLOC), pfnf (PFNFCIFREE), pfnopen (PFNFCIOPEN), pfnread (PFNFCIREAD), pfnwrite (PFNFCIWRITE), pfnclose (PFNFCICLOSE), pfnseek (PFNFCISEEK), pfndelete (PFNFCIDELETE), pfnfcigtf (PFNFCIGETTEMPFILE), pccab (CCAB*), pv (void* optional)
r1, _, err := procFCICreate.Call(
	uintptr(perf),
	uintptr(pfnfcifp),
	uintptr(pfna),
	uintptr(pfnf),
	uintptr(pfnopen),
	uintptr(pfnread),
	uintptr(pfnwrite),
	uintptr(pfnclose),
	uintptr(pfnseek),
	uintptr(pfndelete),
	uintptr(pfnfcigtf),
	uintptr(pccab),
	uintptr(pv),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // void*
function FCICreate(
  perf: Pointer;   // ERF*
  pfnfcifp: Pointer;   // PFNFCIFILEPLACED
  pfna: Pointer;   // PFNFCIALLOC
  pfnf: Pointer;   // PFNFCIFREE
  pfnopen: Pointer;   // PFNFCIOPEN
  pfnread: Pointer;   // PFNFCIREAD
  pfnwrite: Pointer;   // PFNFCIWRITE
  pfnclose: Pointer;   // PFNFCICLOSE
  pfnseek: Pointer;   // PFNFCISEEK
  pfndelete: Pointer;   // PFNFCIDELETE
  pfnfcigtf: Pointer;   // PFNFCIGETTEMPFILE
  pccab: Pointer;   // CCAB*
  pv: Pointer   // void* optional
): Pointer; cdecl;
  external 'Cabinet.dll' name 'FCICreate';
result := DllCall("Cabinet\FCICreate"
    , "Ptr", perf   ; ERF*
    , "Ptr", pfnfcifp   ; PFNFCIFILEPLACED
    , "Ptr", pfna   ; PFNFCIALLOC
    , "Ptr", pfnf   ; PFNFCIFREE
    , "Ptr", pfnopen   ; PFNFCIOPEN
    , "Ptr", pfnread   ; PFNFCIREAD
    , "Ptr", pfnwrite   ; PFNFCIWRITE
    , "Ptr", pfnclose   ; PFNFCICLOSE
    , "Ptr", pfnseek   ; PFNFCISEEK
    , "Ptr", pfndelete   ; PFNFCIDELETE
    , "Ptr", pfnfcigtf   ; PFNFCIGETTEMPFILE
    , "Ptr", pccab   ; CCAB*
    , "Ptr", pv   ; void* optional
    , "Cdecl Ptr")   ; return: void*
●FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv) = DLL("Cabinet.dll", "void* FCICreate(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*)")
# 呼び出し: FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
# perf : ERF* -> "void*"
# pfnfcifp : PFNFCIFILEPLACED -> "void*"
# pfna : PFNFCIALLOC -> "void*"
# pfnf : PFNFCIFREE -> "void*"
# pfnopen : PFNFCIOPEN -> "void*"
# pfnread : PFNFCIREAD -> "void*"
# pfnwrite : PFNFCIWRITE -> "void*"
# pfnclose : PFNFCICLOSE -> "void*"
# pfnseek : PFNFCISEEK -> "void*"
# pfndelete : PFNFCIDELETE -> "void*"
# pfnfcigtf : PFNFCIGETTEMPFILE -> "void*"
# pccab : CCAB* -> "void*"
# pv : void* optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※cdecl関数。DLL()宣言はstdcall前提。cdeclは EXEC_PTR(`cdecl`,…) を使用。
const std = @import("std");

extern "cabinet" fn FCICreate(
    perf: [*c]ERF, // ERF*
    pfnfcifp: ?*anyopaque, // PFNFCIFILEPLACED
    pfna: ?*anyopaque, // PFNFCIALLOC
    pfnf: ?*anyopaque, // PFNFCIFREE
    pfnopen: ?*anyopaque, // PFNFCIOPEN
    pfnread: ?*anyopaque, // PFNFCIREAD
    pfnwrite: ?*anyopaque, // PFNFCIWRITE
    pfnclose: ?*anyopaque, // PFNFCICLOSE
    pfnseek: ?*anyopaque, // PFNFCISEEK
    pfndelete: ?*anyopaque, // PFNFCIDELETE
    pfnfcigtf: ?*anyopaque, // PFNFCIGETTEMPFILE
    pccab: [*c]CCAB, // CCAB*
    pv: ?*anyopaque // void* optional
) callconv(.c) ?*anyopaque;
proc FCICreate(
    perf: ptr ERF,  # ERF*
    pfnfcifp: pointer,  # PFNFCIFILEPLACED
    pfna: pointer,  # PFNFCIALLOC
    pfnf: pointer,  # PFNFCIFREE
    pfnopen: pointer,  # PFNFCIOPEN
    pfnread: pointer,  # PFNFCIREAD
    pfnwrite: pointer,  # PFNFCIWRITE
    pfnclose: pointer,  # PFNFCICLOSE
    pfnseek: pointer,  # PFNFCISEEK
    pfndelete: pointer,  # PFNFCIDELETE
    pfnfcigtf: pointer,  # PFNFCIGETTEMPFILE
    pccab: ptr CCAB,  # CCAB*
    pv: pointer  # void* optional
): pointer {.importc: "FCICreate", cdecl, dynlib: "Cabinet.dll".}
pragma(lib, "cabinet");
extern(C)
void* FCICreate(
    ERF* perf,   // ERF*
    void* pfnfcifp,   // PFNFCIFILEPLACED
    void* pfna,   // PFNFCIALLOC
    void* pfnf,   // PFNFCIFREE
    void* pfnopen,   // PFNFCIOPEN
    void* pfnread,   // PFNFCIREAD
    void* pfnwrite,   // PFNFCIWRITE
    void* pfnclose,   // PFNFCICLOSE
    void* pfnseek,   // PFNFCISEEK
    void* pfndelete,   // PFNFCIDELETE
    void* pfnfcigtf,   // PFNFCIGETTEMPFILE
    CCAB* pccab,   // CCAB*
    void* pv   // void* optional
);
ccall((:FCICreate, "Cabinet.dll"), Ptr{Cvoid},
      (Ptr{ERF}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{CCAB}, Ptr{Cvoid}),
      perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
# perf : ERF* -> Ptr{ERF}
# pfnfcifp : PFNFCIFILEPLACED -> Ptr{Cvoid}
# pfna : PFNFCIALLOC -> Ptr{Cvoid}
# pfnf : PFNFCIFREE -> Ptr{Cvoid}
# pfnopen : PFNFCIOPEN -> Ptr{Cvoid}
# pfnread : PFNFCIREAD -> Ptr{Cvoid}
# pfnwrite : PFNFCIWRITE -> Ptr{Cvoid}
# pfnclose : PFNFCICLOSE -> Ptr{Cvoid}
# pfnseek : PFNFCISEEK -> Ptr{Cvoid}
# pfndelete : PFNFCIDELETE -> Ptr{Cvoid}
# pfnfcigtf : PFNFCIGETTEMPFILE -> Ptr{Cvoid}
# pccab : CCAB* -> Ptr{CCAB}
# pv : void* optional -> Ptr{Cvoid}
local ffi = require("ffi")
ffi.cdef[[
void* FCICreate(
    void* perf,
    void* pfnfcifp,
    void* pfna,
    void* pfnf,
    void* pfnopen,
    void* pfnread,
    void* pfnwrite,
    void* pfnclose,
    void* pfnseek,
    void* pfndelete,
    void* pfnfcigtf,
    void* pccab,
    void* pv);
]]
local cabinet = ffi.load("cabinet")
-- cabinet.FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
-- perf : ERF*
-- pfnfcifp : PFNFCIFILEPLACED
-- pfna : PFNFCIALLOC
-- pfnf : PFNFCIFREE
-- pfnopen : PFNFCIOPEN
-- pfnread : PFNFCIREAD
-- pfnwrite : PFNFCIWRITE
-- pfnclose : PFNFCICLOSE
-- pfnseek : PFNFCISEEK
-- pfndelete : PFNFCIDELETE
-- pfnfcigtf : PFNFCIGETTEMPFILE
-- pccab : CCAB*
-- pv : void* optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('Cabinet.dll');
const FCICreate = lib.func('__cdecl', 'FCICreate', 'void *', ['void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *', 'void *']);
// FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
// perf : ERF* -> 'void *'
// pfnfcifp : PFNFCIFILEPLACED -> 'void *'
// pfna : PFNFCIALLOC -> 'void *'
// pfnf : PFNFCIFREE -> 'void *'
// pfnopen : PFNFCIOPEN -> 'void *'
// pfnread : PFNFCIREAD -> 'void *'
// pfnwrite : PFNFCIWRITE -> 'void *'
// pfnclose : PFNFCICLOSE -> 'void *'
// pfnseek : PFNFCISEEK -> 'void *'
// pfndelete : PFNFCIDELETE -> 'void *'
// pfnfcigtf : PFNFCIGETTEMPFILE -> 'void *'
// pccab : CCAB* -> 'void *'
// pv : void* optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
// コールバック(関数ポインタ)は koffi.proto/koffi.register で型を定義して渡す(素の void* では JS 関数を渡せない)。
const lib = Deno.dlopen("Cabinet.dll", {
  FCICreate: { parameters: ["pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer"], result: "pointer" },
});
// lib.symbols.FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv)
// perf : ERF* -> "pointer"
// pfnfcifp : PFNFCIFILEPLACED -> "pointer"
// pfna : PFNFCIALLOC -> "pointer"
// pfnf : PFNFCIFREE -> "pointer"
// pfnopen : PFNFCIOPEN -> "pointer"
// pfnread : PFNFCIREAD -> "pointer"
// pfnwrite : PFNFCIWRITE -> "pointer"
// pfnclose : PFNFCICLOSE -> "pointer"
// pfnseek : PFNFCISEEK -> "pointer"
// pfndelete : PFNFCIDELETE -> "pointer"
// pfnfcigtf : PFNFCIGETTEMPFILE -> "pointer"
// pccab : CCAB* -> "pointer"
// pv : void* optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
void* FCICreate(
    void* perf,
    void* pfnfcifp,
    void* pfna,
    void* pfnf,
    void* pfnopen,
    void* pfnread,
    void* pfnwrite,
    void* pfnclose,
    void* pfnseek,
    void* pfndelete,
    void* pfnfcigtf,
    void* pccab,
    void* pv);
C, "Cabinet.dll");
// $ffi->FCICreate(perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf, pccab, pv);
// perf : ERF*
// pfnfcifp : PFNFCIFILEPLACED
// pfna : PFNFCIALLOC
// pfnf : PFNFCIFREE
// pfnopen : PFNFCIOPEN
// pfnread : PFNFCIREAD
// pfnwrite : PFNFCIWRITE
// pfnclose : PFNFCICLOSE
// pfnseek : PFNFCISEEK
// pfndelete : PFNFCIDELETE
// pfnfcigtf : PFNFCIGETTEMPFILE
// pccab : CCAB*
// pv : void* optional
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Cabinet extends Library {
    Cabinet INSTANCE = Native.load("cabinet", Cabinet.class);
    Pointer FCICreate(
        Pointer perf,   // ERF*
        Callback pfnfcifp,   // PFNFCIFILEPLACED
        Callback pfna,   // PFNFCIALLOC
        Callback pfnf,   // PFNFCIFREE
        Callback pfnopen,   // PFNFCIOPEN
        Callback pfnread,   // PFNFCIREAD
        Callback pfnwrite,   // PFNFCIWRITE
        Callback pfnclose,   // PFNFCICLOSE
        Callback pfnseek,   // PFNFCISEEK
        Callback pfndelete,   // PFNFCIDELETE
        Callback pfnfcigtf,   // PFNFCIGETTEMPFILE
        Pointer pccab,   // CCAB*
        Pointer pv   // void* optional
    );
}
@[Link("cabinet")]
lib LibCabinet
  fun FCICreate = FCICreate(
    perf : ERF*,   # ERF*
    pfnfcifp : Void*,   # PFNFCIFILEPLACED
    pfna : Void*,   # PFNFCIALLOC
    pfnf : Void*,   # PFNFCIFREE
    pfnopen : Void*,   # PFNFCIOPEN
    pfnread : Void*,   # PFNFCIREAD
    pfnwrite : Void*,   # PFNFCIWRITE
    pfnclose : Void*,   # PFNFCICLOSE
    pfnseek : Void*,   # PFNFCISEEK
    pfndelete : Void*,   # PFNFCIDELETE
    pfnfcigtf : Void*,   # PFNFCIGETTEMPFILE
    pccab : CCAB*,   # CCAB*
    pv : Void*   # void* optional
  ) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef FCICreateNative = Pointer<Void> Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef FCICreateDart = Pointer<Void> Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final FCICreate = DynamicLibrary.open('Cabinet.dll')
    .lookupFunction<FCICreateNative, FCICreateDart>('FCICreate');
// perf : ERF* -> Pointer<Void>
// pfnfcifp : PFNFCIFILEPLACED -> Pointer<Void>
// pfna : PFNFCIALLOC -> Pointer<Void>
// pfnf : PFNFCIFREE -> Pointer<Void>
// pfnopen : PFNFCIOPEN -> Pointer<Void>
// pfnread : PFNFCIREAD -> Pointer<Void>
// pfnwrite : PFNFCIWRITE -> Pointer<Void>
// pfnclose : PFNFCICLOSE -> Pointer<Void>
// pfnseek : PFNFCISEEK -> Pointer<Void>
// pfndelete : PFNFCIDELETE -> Pointer<Void>
// pfnfcigtf : PFNFCIGETTEMPFILE -> Pointer<Void>
// pccab : CCAB* -> Pointer<Void>
// pv : void* optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function FCICreate(
  perf: Pointer;   // ERF*
  pfnfcifp: Pointer;   // PFNFCIFILEPLACED
  pfna: Pointer;   // PFNFCIALLOC
  pfnf: Pointer;   // PFNFCIFREE
  pfnopen: Pointer;   // PFNFCIOPEN
  pfnread: Pointer;   // PFNFCIREAD
  pfnwrite: Pointer;   // PFNFCIWRITE
  pfnclose: Pointer;   // PFNFCICLOSE
  pfnseek: Pointer;   // PFNFCISEEK
  pfndelete: Pointer;   // PFNFCIDELETE
  pfnfcigtf: Pointer;   // PFNFCIGETTEMPFILE
  pccab: Pointer;   // CCAB*
  pv: Pointer   // void* optional
): Pointer; cdecl;
  external 'Cabinet.dll' name 'FCICreate';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import ccall safe "FCICreate"
  c_FCICreate :: Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> IO (Ptr ())
-- perf : ERF* -> Ptr ()
-- pfnfcifp : PFNFCIFILEPLACED -> Ptr ()
-- pfna : PFNFCIALLOC -> Ptr ()
-- pfnf : PFNFCIFREE -> Ptr ()
-- pfnopen : PFNFCIOPEN -> Ptr ()
-- pfnread : PFNFCIREAD -> Ptr ()
-- pfnwrite : PFNFCIWRITE -> Ptr ()
-- pfnclose : PFNFCICLOSE -> Ptr ()
-- pfnseek : PFNFCISEEK -> Ptr ()
-- pfndelete : PFNFCIDELETE -> Ptr ()
-- pfnfcigtf : PFNFCIGETTEMPFILE -> Ptr ()
-- pccab : CCAB* -> Ptr ()
-- pv : void* optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let fcicreate =
  foreign "FCICreate"
    ((ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning (ptr void))
(* perf : ERF* -> (ptr void) *)
(* pfnfcifp : PFNFCIFILEPLACED -> (ptr void) *)
(* pfna : PFNFCIALLOC -> (ptr void) *)
(* pfnf : PFNFCIFREE -> (ptr void) *)
(* pfnopen : PFNFCIOPEN -> (ptr void) *)
(* pfnread : PFNFCIREAD -> (ptr void) *)
(* pfnwrite : PFNFCIWRITE -> (ptr void) *)
(* pfnclose : PFNFCICLOSE -> (ptr void) *)
(* pfnseek : PFNFCISEEK -> (ptr void) *)
(* pfndelete : PFNFCIDELETE -> (ptr void) *)
(* pfnfcigtf : PFNFCIGETTEMPFILE -> (ptr void) *)
(* pccab : CCAB* -> (ptr void) *)
(* pv : void* optional -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library cabinet (t "Cabinet.dll"))
(cffi:use-foreign-library cabinet)

(cffi:defcfun ("FCICreate" fcicreate :convention :cdecl) :pointer
  (perf :pointer)   ; ERF*
  (pfnfcifp :pointer)   ; PFNFCIFILEPLACED
  (pfna :pointer)   ; PFNFCIALLOC
  (pfnf :pointer)   ; PFNFCIFREE
  (pfnopen :pointer)   ; PFNFCIOPEN
  (pfnread :pointer)   ; PFNFCIREAD
  (pfnwrite :pointer)   ; PFNFCIWRITE
  (pfnclose :pointer)   ; PFNFCICLOSE
  (pfnseek :pointer)   ; PFNFCISEEK
  (pfndelete :pointer)   ; PFNFCIDELETE
  (pfnfcigtf :pointer)   ; PFNFCIGETTEMPFILE
  (pccab :pointer)   ; CCAB*
  (pv :pointer))   ; void* optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $FCICreate = Win32::API::More->new('Cabinet',
    'LPVOID FCICreate(LPVOID perf, LPVOID pfnfcifp, LPVOID pfna, LPVOID pfnf, LPVOID pfnopen, LPVOID pfnread, LPVOID pfnwrite, LPVOID pfnclose, LPVOID pfnseek, LPVOID pfndelete, LPVOID pfnfcigtf, LPVOID pccab, LPVOID pv)');
# my $ret = $FCICreate->Call($perf, $pfnfcifp, $pfna, $pfnf, $pfnopen, $pfnread, $pfnwrite, $pfnclose, $pfnseek, $pfndelete, $pfnfcigtf, $pccab, $pv);
# perf : ERF* -> LPVOID
# pfnfcifp : PFNFCIFILEPLACED -> LPVOID
# pfna : PFNFCIALLOC -> LPVOID
# pfnf : PFNFCIFREE -> LPVOID
# pfnopen : PFNFCIOPEN -> LPVOID
# pfnread : PFNFCIREAD -> LPVOID
# pfnwrite : PFNFCIWRITE -> LPVOID
# pfnclose : PFNFCICLOSE -> LPVOID
# pfnseek : PFNFCISEEK -> LPVOID
# pfndelete : PFNFCIDELETE -> LPVOID
# pfnfcigtf : PFNFCIGETTEMPFILE -> LPVOID
# pccab : CCAB* -> LPVOID
# pv : void* optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。

関連項目

使用する型