CからC#を呼ぶ“もっと素直で簡単な方法”

C言語のEXEからC++/CLIDLLを経由してC#DLLを呼び出す)

 

二つのdllhellocli.dllhellocs.dll)については

hellocs.netmoduleをビルドし

hellocli.dllに静的リンクすれば

一つのdllhellocli.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.cpphellocs.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]);

                            }

              }

}

 

ダウンロード1 ダウンロード2 ダウンロード3 ダウンロード4 ダウンロード5 ダウンロード6

cからExcelを使う

ダウンロード1 ダウンロード2 ダウンロード3 ダウンロード4 ダウンロード5 ダウンロード6



感想などは



↑↓Marshal::FreeHGlobalが見当たらない・メモリーリーク!