※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

C/C++への橋渡し


C++/CLIからC/C++へ数値を渡す

普通に呼ぶだけです。


C++/CLIからC/C++へ文字列を渡す

#include "stdafx.h"
using namespace System; 
using namespace System::Runtime::InteropServices; 

#include "stdio.h"
extern "C" void testFunc(char* p) {
   puts(p);
}
int main(array<System::String ^> ^args) {

   String^ str = "abあcdefg";

   // StringToHGlobalXXXは、変換してアンマネージメモリにコピーしてくれる
   System::IntPtr pp = Marshal::StringToHGlobalAnsi(str);
   // !!!StringTOHGlobalUniを使うと、半角英数字も1文字2バイトで変換されてしまう
   testFunc(static_cast<char*>(pp.ToPointer()));
   // アンマネージメモリの開放
   Marshal::FreeHGlobal(pp);

   return 0;
} 


C++/CLIからC/C++へポインタを渡す

pin_ptrを使います。MSDNでは、「固定ポインタ」と解説されています。
#include "stdafx.h"
using namespace System; 

extern "C" void testFunc(int* p) {
   (*p)++;
}
int main(array<System::String ^> ^args) {

   int intVar = 3;
   Console::WriteLine(intVar);    // 3と表示される。

   pin_ptr<int>pinPtr = &intVar;  // intVarのアドレスをpinPtrに代入して
   testFunc(pinPtr);              // pinPtrでテスト関数を呼び出す。

   Console::WriteLine(intVar);    // 4と表示される。

   return 0;
} 

C++/CLIからC/C++へ配列を渡す

アンマネージメモリを確保し、そこに配列をコピーします。
#include "stdafx.h"
using namespace System; 
using namespace System::Runtime::InteropServices; 

// テスト用の古い関数
#include "stdio.h"
extern "C" void testFunc(int* p, int s) {
   for (int i = 0; i < s; i ++) {
       printf("No.%d = %d\n", i, p[i]);
   }
}
int main(array<System::String ^> ^args) {

   array<int>^ srcArray = gcnew array<int>{ 1, 2, 3, 4, 5};
   // アンマネージメモリの確保
   IntPtr pWrkMem = Marshal::AllocHGlobal(sizeof(int)*srcArray->Length);
   // 確保したメモリに配列をコピー
   Marshal::Copy(srcArray, 0, pWrkMem, manarr->Length);
   // テスト関数の呼び出し
   testFunc( static_cast<int*>(pWrkMem.ToPointer()), srcArray->Length);
   // アンマネージメモリの開放
   Marshal::FreeHGlobal(pWrkMem);

   return 0;
}