CからC#を呼ぶ“もっと素直で簡単な方法”
(C言語のEXEからC++/CLIのDLLを経由してC#のDLLを呼び出す)
二つのdll(hellocli.dllとhellocs.dll)については
hellocs.netmoduleをビルドし
hellocli.dllに静的リンクすれば
一つのdll(hellocli.dll)にまとめることができる(別記)
コード例
helloc.cpp
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
HMODULE mhellocli = LoadLibrary("hellocli.dll");
if (mhellocli == NULL)
{
printf("hellocli.dllをロードできません\r\n");
exit(1);
}
int(__cdecl * loaddll)(void);
loaddll = (int(__cdecl *)(void))GetProcAddress(mhellocli, "loaddll");
if (loaddll() != 0)
{
printf("hellocs.dllをロードできません\r\n");
FreeLibrary(mhellocli);
exit(1);
}
char *(__cdecl * methodc1)(const char *,const char *,char *);
methodc1 = (char *(__cdecl *)(const char *,const char *,char *))GetProcAddress(mhellocli, "methodcli1");
char * buff00 = (char *)malloc(100);
if (buff00 == NULL)
{
printf("malloc error\r\n");
FreeLibrary(mhellocli);
exit(1);
}
const char * str01;
if (argc >= 2)
str01 = argv[1];
else
str01 = "Hello world";
const char * str02;
if (argc >= 3)
str02 = argv[2];
else
str02 = "ハローワールド";
memset(buff00,' ',99);
* (buff00 + 99) = '\0';
printf("%s\r\n",methodc1(str01,str02,buff00));
char *(__cdecl * methodc2)(const char *,const char *,const char *,char *);
methodc2 = (char *(__cdecl *)(const char *,const char *,const char *,char *))GetProcAddress(mhellocli, "methodcli2");
const char * str03;
if (argc >= 4)
str03 = argv[3];
else
str03 = "グッドバイワールド";
memset(buff00,' ',99);
* (buff00 + 99) = '\0';
printf("%s\r\n",methodc2(str01,str02,str03,buff00));
FreeLibrary(mhellocli);
free(buff00);
return 0;
}
hellocli.cpp(hellocs.dllを明示的に読み込む)
#include <stdio.h>
#include <windows.h>
//#using "hellocs.dll"
//#using "hellocs.netmodule"
//#include <gcroot.h>
//gcroot<hellocs::hellocscls^> cls;
using namespace System;
using namespace System::Runtime::InteropServices;
extern "C" {
__declspec(dllexport) int loaddll(void);
__declspec(dllexport) char * methodcli1( const char * string01, const char * string02, char * buff00);
__declspec(dllexport) char * methodcli2( const char * string01, const char * string02, const char * string03, char * buff00);
}
ref class refcls
{
public:
static hellocs::hellocscls^ cls;
};
void loadcsdll(void)
{
refcls::cls = gcnew hellocs::hellocscls();
}
int loaddll(void)
{
try
{
loadcsdll();
}
catch (Exception^ e)
{
return -1;
}
return 0;
}
char * methodcli1( const char * string01, const char * string02, char * buff00)
{
unsigned int len = strlen(buff00);
unsigned int n = MultiByteToWideChar(CP_ACP, 0, string01, -1, NULL, 0);
char * param1 = (char *)calloc(1,n*2);
if (param1 == NULL)
{
strcpy_s(buff00, len + 1, "calloc error");
return buff00;
}
MultiByteToWideChar(CP_ACP, 0, string01, -1, (LPWSTR)param1, n);
n = MultiByteToWideChar(CP_ACP, 0, string02, -1, NULL, 0 );
char * param2 = (char *)calloc(1,n*2);
if (param2 == NULL)
{
strcpy_s(buff00, len + 1, "calloc error");
free(param1);
return buff00;
}
MultiByteToWideChar(CP_ACP, 0, string02, -1, (LPWSTR)param2, n);
char * ret01 = (char *)Marshal::StringToHGlobalAnsi(refcls::cls->methodcs1( (LPWSTR)param1, (LPWSTR)param2)).ToPointer();
n = strlen(ret01);
if (len>=n)
{
strcpy_s(buff00, len + 1, ret01);
}
else
{
strcpy_s(buff00, len+1, "バッファが足りません(methodcli1)");
}
Marshal::FreeHGlobal((IntPtr)ret01);
free(param1);
free(param2);
return buff00;
}
char * methodcli2( const char * string01, const char * string02, const char * string03, char * buff00)
{
array<String^>^ arr = gcnew array<String^>(3);
arr[0] = gcnew String(string01);
arr[1] = gcnew String(string02);
arr[2] = gcnew String(string03);
char * ret01 = (char *)Marshal::StringToHGlobalAnsi(refcls::cls->methodcs2( arr)).ToPointer();
unsigned int len = strlen(buff00);
unsigned int n = strlen(ret01);
if (len>=n)
{
strcpy_s(buff00, len + 1, ret01);
}
else
{
strcpy_s(buff00, len + 1, "バッファが足りません(methodcli2)");
}
Marshal::FreeHGlobal((IntPtr)ret01);
return buff00;
}
hellocs.cs
//using System.Runtime.InteropServices;
namespace hellocs
{
public unsafe class hellocscls
{
public string methodcs1(char * str01, char * str02)
{
string ret01 = new string(str01);
string ret02 = new string(str02);
return (ret01 + " " + ret02);
}
public string methodcs2(string[] arr01)
{
return (arr01[0] + " " + arr01[1] + " " + arr01[2]);
}
}
}
cからExcelを使う
ダウンロード1 ダウンロード2 ダウンロード3 ダウンロード4 ダウンロード5 ダウンロード6↑↓Marshal::FreeHGlobalが見当たらない・メモリーリーク!