最終更新日 2024-09-25

文字列の扱い方① [MarshalAs(UnmanagedType.LPWStr)] String

概要

文字列型をどうするかは悩ましいところです。
考えられる選択肢としては、大別して以下の3通りとなることでしょう。

この3つの方法について、順に解説していきます。

[MarshalAs(UnmanagedType.LPWStr)] String を使った書き方

この記述はメモリリークはありますが「移植性が最も高い方法」です。
「DllExport.bat による方法」→「hm.NET による方法」への移行、もしくは、「COMによる方法」への移行、
どちらに将来移行するにしても、
[DllExport] と [MarshalAs(UnmanagedType.LPWStr)] を削除するだけで、移行が完了し同じ動作(しかもメモリリークなし)が期待できるのがポイントです。

ClassLibrary36.cs
using System;
using System.Runtime.InteropServices;

namespace ClassLibrary36 {

    public class Class1
    {
		// この方法の弱点は、この[return: MarshalAs(UnmanagedType.LPWStr)]によって、メモリリークを起こしてしまうこと
        // プロセスを閉じればどうせ解放されるから、特大級の数百MBの文字列や、数百万回ループ呼び出しが無い限り、実用上問題がないという考え方
        [DllExport]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        static String abc([MarshalAs(UnmanagedType.LPWStr)] String a, [MarshalAs(UnmanagedType.LPWStr)] String b)
        {
            return a + b;
        }

    }
}

呼び出し側

ClassLibrary36.mac
#DLL = loaddll( currentmacrodirectory + @"\ClassLibrary36.dll");

$add_str = dllfuncstrw( #DLL, "abc", "あいうえお", "素麺");
message($add_str);