やりたいこと
引数で文字列を返すメソッドをSWIGで生成したい。
SWIG 4.0.2はstd::string*に対応していないので手動で対応してみる。
Sample.h
class Sample {
public:
void GetSettingName(std::string* settingName) {
*settingName = "ABC";
}
};
C#側では以下のように呼び出す。
Program.cs
static void Main() {
var sample = new Sample();
sample.GetSettingName(out string settingName);
}
実装例
sample.iの設定でC++側のC#用メソッドが作成される。
CSharp_Sample_GetSettingNameはC#向けに公開したいメソッド。
%ignoreで該当メソッドを自動生成しないようにする。
生成されたC#側のクラスにメソッドを追加したいのでpartial指定する。
sample.i
%module example
%typemap(csclassmodifiers) Sample "public partial class"
%ignore Sample::GetSettingName(std::string* settingName);
%{
# include <windows.h>
# include "Sample.h"
%}
%include <windows.i>
%include "Sample.h"
%{
# ifdef __cplusplus
extern "C"
# endif
SWIGEXPORT void SWIGSTDCALL CSharp_Sample_GetSettingName(
void * self, BSTR* bstrSettingName) {
std::string settingName;
((Sample*)self)->GetSettingName(&settingName);
*bstrSettingName = ::SysAllocStringByteLen(
settingName.c_str(), settingName.length());
}
%}
手動で作成したC++側のメソッドを呼び出す。
Sample.manual.cs
using System.Runtime.InteropServices;
partial class Sample {
private static class NativeMethods {
[DllImport("example", EntryPoint = "CSharp_Config_GetSettingName")]
public static extern void GetSettingName(
HandleRef self,
[MarshalAs(UnmanagedType.AnsiBStr)] out string bstrSettingName);
}
public void GetSettingName(out string settingName) {
NativeMethods.GetSettingName(swigCPtr, out settingName);
}
}