JV-Linkの64bit版対応時にこれまでのJVGets時の対処でSafeArrayを使っている部分がエラーだしたので、その対応色々と試してSafeArray無しで行ける方法を見つけて対応してたんですが、そもそもこれって64bitでなきゃ出来ない訳じゃないだろうって思って32bitでもSafeArray無しで行けるか、ざっくりコード修正してフルセットアップ実行中。
Visual Studioのデバッグモードでフルセットアップ開始して既に3割以上来てますが、じわじわ使用メモリ増えてる感じはしますけど、メモリリークとか例のJVGetsで読み出しの度に解放ってのが出来てないで増えている訳ではなく、単にプロセスが進むにつれて増えてるだけな気がしてます。なので、この方法は問題ないって判断にします。
これ、解放がしっかり出来てないとフルセットアップ中に死ぬのかな?
既に半分以上過ぎた状態でこんなものなんですが、ああ、これSafeArrayの時と比べればわかりやすかったかもだが、もう、また戻して試すのは辛いorz
Copilotにちょっと相談してると、今のやり方はSafeArrayを使わない方式ではなく、「SafeArray を .NET が自動で byte[] に変換する方式」だと言われた(笑) まあ、でも、安全な使い方だって言われたから良いか。
public static int SafeJVGets(out byte[] bBuff, out string strFileName, int iBuffSize = 105000)
{
bBuff = null;
object objBuff = new byte[0];
int iReturnCode = SaraD.clsJVLink.JVGets(ref objBuff, iBuffSize, out strFileName);
if (iReturnCode > 0 && objBuff is byte[] returnedBytes)
{
if (returnedBytes.Length == iReturnCode)
{
bBuff = returnedBytes;
}
else
{
bBuff = new byte[iReturnCode];
Array.Copy(returnedBytes, bBuff, iReturnCode);
}
}
return iReturnCode;
}
これが実際に使っている今のコードです。
随分時間が掛かったのは、裏でランキング学習が走ってるのとざっくりなコードでまだ余分な部分があるデバッグモードだからなのかは分からないが問題なくフルセットアップ出来るので採用します。これで余分なSafeArray関連のDLL周りの宣言不要になるしスッキリ出来る感じ。
追記 2026.8.16 21:43
やはりちょっと時間掛かってるのでCopilotに確認すると修正案って
public static int SafeJVGets(out byte[] bBuff, out string strFileName, int iBuffSize = 105000)
{
object objBuff = new byte[0];
int iReturnCode = SaraD.clsJVLink.JVGets(ref objBuff, iBuffSize, out strFileName);
if (iReturnCode > 0 && objBuff is byte[] returnedBytes)
{
// ★高速化ポイント:論理長に揃える(昔の Marshal.Copy と同じ動作)
if (returnedBytes.Length != iReturnCode)
{
// returnedBytes が SafeArray の物理長(例:4096)で来た場合、
// 昔のコードと同じく「論理長 iReturnCode」に揃える
bBuff = new byte[iReturnCode];
Array.Copy(returnedBytes, bBuff, iReturnCode);
}
else
{
// ★ゼロコピー:物理長が論理長と一致している場合はそのまま使う
bBuff = returnedBytes;
}
}
else
{
// EOF or エラー
bBuff = null;
}
ほぼ同じ条件下で
10分弱短縮してるので良しとします。
追記 2026.8.17
昨夜上記の修正を32bit版にも適用してあったけど、疲れて本日帰宅後に試しました。昨日はうらでランキング学習とかも動かしてたけど、本日はそれ無しで素でフルセットアップさせました。
35分弱なら十分ですね^^
0 件のコメント:
コメントを投稿