C#(.NET Framework)でJVGetsのbuffが常にNULLになります

お世話になっております。

現在、Visual Studio 2022(x86)でJRA-VAN Data Lab. SDK Ver4.9.0.2を使用してC#アプリケーションを開発しています。

開発環境

- SDK:JRA-VAN Data Lab. SDK Ver4.9.0.2

- Visual Studio 2022

- .NET Framework

- プラットフォームターゲット:x86

- Interop.JVDTLabLib

  • 相互運用型の埋め込み:False

現在の状況

以下は正常に動作しています。

JVInit : 0

JVOpen : 0

読込件数 : 50

DL件数 : 0

LastTimeStamp : 20260713133747

JVOpenは正常終了しています。

その後、以下のようにJVGetsを呼び出しています。

object buff = null;

string fileName;

int rc = _jv.JVGets(

ref buff,

110000,

out fileName);

実行結果は

ReturnCode : 80

FileName : JGDW2026070420260703112847.jvd

buff = NULL

となります。

ReturnCode=80なのでレコードは取得できているようですが、buffが常にNULLです。

試したこと

- Visual Studioを管理者で実行

- x86へ変更

- 相互運用型の埋め込み=False

- JVGets

- JVRead

JVReadについては

JVRead(out string buff, out int size, out string fileName)

を試しましたが、実行時に

System.Runtime.InteropServices.SEHException

外部コンポーネントが例外をスローしました

となりました。

質問

C#(Visual Studio 2022、SDK4.9.0.2)でJVGetsを使用する場合、

1. “object buff” の受け取り方はこれで正しいでしょうか。

2. SAFEARRAYをMarshal.Copy等で取得する必要がありますか。

3. SDK4.9.0.2で動作するC#のサンプルがあれば教えていただけないでしょうか。

よろしくお願いいたします。

@lu4fer さん、こんばんは。

以前こちらに書いたスレがリンクは貼れますが一覧には出てないので重複にはなりますが書きますね。ちょっと厄介なんですが、以前の古い掲示板の時に自分も当時の掲示板の有志の方に教えて頂きました。

まず、こちらの定義が必要です

    // JVGets用
    [DllImport("Oleaut32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr SafeArrayCreateVector(VarEnum vt, int lLbound, uint cElements);
    [DllImport("Oleaut32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern uint SafeArrayDestroy(IntPtr pSafeArray);
    [DllImport("Oleaut32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern uint SafeArrayAccessData(IntPtr pSafeArray, ref IntPtr ppvData);
    [DllImport("Oleaut32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern uint SafeArrayUnaccessData(IntPtr pSafeArray);
    [DllImport("Oleaut32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern uint SafeArrayGetUBound(IntPtr pSafeArray, uint nDim, ref int lUbound);

で、実際の呼び出しは

                // JVGetsとSafeArray関連
                int iBuffSize = 1024 * 1024;
                const int iNameSize = 256;
                strFileName = new string('\0', iNameSize);
                object objBuff = (object)(IntPtr)0;

としておいて

                    iReturnCode = SaraD.clsJVLink.JVGets(ref objBuff, iBuffSize, out strFileName);
                    if (iReturnCode > 0)
                    {
                        bBuff = new byte[iReturnCode];
                        IntPtr pSafeArray = (IntPtr)(int)objBuff;
                        try
                        {
                            uint hr;

                            IntPtr ppvData = (IntPtr)0;
                            hr = SafeArrayAccessData(pSafeArray, ref ppvData);
                            if (hr != 0) throw new System.Exception(hr.ToString());

                            Marshal.Copy(ppvData, bBuff, 0, iReturnCode);
                            // strBuff = Marshal.PtrToStringAnsi(ppvData);

                            SafeArrayUnaccessData(pSafeArray);
                        }
                        finally
                        {
                            SafeArrayDestroy(pSafeArray);
                        }
                    }

としてます。詳細な説明は自分には出来ませんが、自分はこれで問題なく動いてます。

詳しく説明できる方が居れば、何かトラブルがあった場合にアドバイスくれるかもですが、もし、自力で解決出来ず、こちらにそれに対して質問投げて回答が無いようだったらJVReadで行くしかないかもです。

たいしたアドバイスは出来ませんが、自分のアプリで動いてるコードをお見せする事は出来るので上げてみました。

SameNoEsaさん

ありがとうございます!

早速試してみたところ、上手く動きました!

大変ありがとうございました!!

@lu4fer さん、こんばんは。

無事に動いたようで良かったです。上のコードiBuffSizeの初期化が抜けてたので追記しておきました。まあ、この辺りはある程度の数字を入れていれば問題なんだと思います。