• 締切済み

Cで自作したDLLをへC#から文字配列を渡したい

CでDLLを自作したのですが、その引数にchar**型があるのですが、C#から使用するときにどの型の変数を渡せばいいのかわかりません。 色々と調べていくつか同じような事例があったのですが、うまくいきません。 Cで作ったDLLは __declspec(dllexport) int DetectComPorts(LPWORD ComPortTable, int ComPortMax, char **ComPortDesc) です。この中で「char **ComPortDesc」が問題です。 Cで書いたプログラムからはこのDLLが使用できることを確認しています。 Cの場合はchar**型の適当な変数を作ってmallocでメモリ確保してこの関数に渡して実行するとちゃんとアドレスに目的の文字列が格納されて帰ってきます。 よろしくお願いします

noname#199683
noname#199683

みんなの回答

回答No.2

IntPtrになるかと思いますが、fixedキーワードを使用したほうが手っ取り早いかもしれませんね。 引数を易しくした関数を後もう一つDLLからエクスポートできればそれに越したことはないのですが。 http://limbioliong.wordpress.com/2012/04/17/how-to-implement-pointer-to-pointer-in-c-without-using-unsafe-code/

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

__stdcall を使う。 __cdecl は c言語同士で使用すると時に使用可能です。 言語の壁を越えて、DLL呼び出しをする場合には、__stdcallが使えます。 __stdcallと比べて、__cdeclは、c言語ならではの呼び出し方法を拡張されています。 __stdcallを使うと一部制約を受けますが、それは__stdcallのルールです。 __stdcall http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx __cdecl http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.71).aspx

関連するQ&A

  • PythonでDLLからの戻り値で文字列の場合を正しく表示させたい

    VisualStudio2005でDLLを作成して、Python2.6のctypesモジュールを使って、PythonからC++のルーチンを呼び出す際に、文字列を引数として、文字列を戻り値として使えるようにC++を記述したいのですがどうすればよいのでしょうか? 関数呼び出しは __stdcallです。 __declspec(dllexport) unsigned char* __stdcall Test(const char *s, int n); とした場合、Pythonで戻り値を見るとint型の数値でした。 from ctypes import * lib = windll.LoadLibrary("test.dll") s = lib.Test("abcdefghijk", 3) print s

  • エクセルで自作 DLL の作り方・使い方

    エクセルで使う自作DLLを作ろうとしております。コンパイラーはBorlandでBCC Developerです。 ネットで検索しC++では例えば: extern "C" __declspec(dllexport) int addNum( int _i, int _j ) {return _i+_j;} のようなものを作りました。 ただエクセルVBA上でauto_open イベントにapplication.registerxll("xxx.dll") をしても、上記関数を認識しません・・VBA上に: Public Declare Function addNum Lib "xxx.dll" (.... とすると認識するのですが、上記VBA内での関数の定義を省きたいのですが・・ どなたかご教授いただけますでしょうか?おそらくC++の書き方の問題だとは思っていますが、エクスポートのやり方がイマイチわかっておりません。VBA上でも呼び方がわかっていないのでどなたか教えていただければと思います。

  • Chasen.dllをBCB5で使う方法を教えてください(DLLの使い方)

    形態素解析ツールのChasen Win32版に付属しているchasen.dllを自作のプログラムから呼び出したいと思っています。 ・茶筅 http://chasen.aist-nara.ac.jp/index.html.ja ですが、DLLを使ったことがないのでよくわからずもう何日も困っています。 ヘッダで、まずDLL付属のヘッダー(下記参考資料)をインクルードして、 #include "chadll.h" 自作プログラムのソースで、 HINSTANCE chasenDLL = LoadLibrary("chasen.dll"); でライブラリをロードして、 char *myanalyze = (char *)GetProcAddress(chasenDLL,"analyze"); で関数analyzeを取り出していますが、 analyze()を実際に使うとシンボルの未解決エラーでコンパイルできません。 このDLLはBCBでは使えないのでしょうか。 ---------------------参考資料:DLL付属のサンプルソース /* * dlltest.c - ChaSen dll test program * * Copyright (C) 2000 Nara Institute of Science and Technology * * Author: H.Matsuda <horosi-m@is.aist-nara.ac.jp>, Sep. 2000 */ #include <stdio.h> #include "chadll.h" int main( int argc, char** argv ) { char input[10000] = "これは形態素解析のテストです。"; set_argument_parameters( argc, argv ); printf( "%s", analyze( input ) ); } ---------------------参考資料:DLL付属のヘッダーファイル /* * chasendll.h - ChaSen dll header * * Copyright (C) 2000 Nara Institute of Science and Technology * * Author: H.Matsuda <horosi-m@is.aist-nara.ac.jp>, Sep. 2000 */ __declspec( dllexport ) int set_argument_parameters( int argc, char** argv ); __declspec( dllexport ) char* analyze( char* input );

  • C#での自作DLL(C言語)の並列化

    C言語で自作したDLLをC#で使いたいと考えております。 このDLLの計算量は多くて、値を返すまでに時間がかかります。 そのためにC#のフォームが応答なしになってしまうので並列化したいと思ったのですがうまくいきませんでした。 このDLLは ・int型の戻り値 ・6個の引数 ・上の引数のうち、1つはoutキーワード(ポインタ渡し) です。 どのようにすれば、うまく並列化できるでしょうか。 ご教授お願いいたします。

  • 自作DLLの引数について、ポインタ渡しが??

    VS2005 VC++環境でMFCスマートデバイスDLLを作成しています(アプリ側もVS2005 VC++)。 テスト用のアプリからDLL内の文字列を引数とする関数を呼び出すと、 呼ばれた関数に正しく文字列が渡りません。 以下の場合、func1のw1はデバッガで正しく見れません。 でもw2にtcscpyは成功しw2には正しく値がセットされます。 このときにw1のアドレスがなぜか変更されます。 以下の例では引数が1つですが、2つ以上引数がある時には その他の引数のアドレスもとびます。 func2のl1は正常に見れます。 func3のl1は正常に見れません。 ポインタ渡しするときに異常になるのですが、 原因がさっぱりわかりません。 同じことをWindowsXP用のプロジェクトを作り、 XPで確認するとどれも正常に見れます。 どなたかアドバイスをお願いします。 ----------------------------------------DLL側---------------------------------------- extern "C" __declspec(dllexport) void func1(WCHAR * w1) { WCHAR w2[16] ; _tcscpy(w2,w1); return; } extern "C" __declspec(dllexport) void func2(long l1) { long l2 ; l2 = l1 ; return; } extern "C" __declspec(dllexport) void func3(long *l1) { long l2 ; l2 = *l1 ; return; } ----------------------------------------アプリ側---------------------------------------- extern "C" __declspec(dllimport) void func1(WCHAR *); extern "C" __declspec(dllimport) void func2(long ); extern "C" __declspec(dllimport) void func3(long *); ・・・・中略・・・・ WCHAR a[16] ; _tcscpy(a,_T("ABC")); func1(a); func2(123); long l3 = 123 ; func3(&l3);

  • C++DLLからC#へのコールバックに文字列の配列を渡したい

    教えてください! C++のアンマネージドDLLから、複数のファイル名(文字列)をC#に渡したいです。 ステップとしては、 C#から、C++のDLLの関数を最初に呼んで、コールバック関数を渡しています。 次に、DLLからコールバック関数を呼ぶ時に、複数のファイル名を渡したいです。 以下のコードを動かすと、、 C++からは2つ渡しているつもりなのに、 C#ではfilesがサイズ1のString配列として引数に入ってきます。 なぜでしょう? またどうすればC#から複数受け取れるでしょうか? 教えてください! C# public delegate int StringArrayCallback(String[] files); // C# -> C++ public static int start() { StringArrayCallback cb = new StringArrayCallback(onReceivedFiles); int ret = start(cb); return ret; } // C++ -> C# callback public static int onReceivedFiles(String[] files) { return 1; } C++コード typedef int (__stdcall *OnReceivedFilesProc )(char**); int start( OnReceivedFilesProc callback ) { std::string message1_ = "from C++1"; std::string message2_ = "from C++2"; char* messages_[2] = { (char*)message1_.c_str(), (char*)message2_.c_str() }; int ret_ = callback(messages_); std::cout << "[from c#]" << ret_; }

  • AccessVBAからC言語のDLLの呼び出し方

    初心者です。はじめまして お世話になります。 概要:C言語で作成したDLLをVBAで呼び出す。 タイトルの通り、C言語で作成したDLLをVBAで呼び出したいのですが、うまく 呼び出すことができず、「エラー番号:49 DLLを正しく呼び出せません。」 というエラーが返ってきてしまいます。 DLLの作成手順もしくはDLLの呼び出し方でおかしな所があればご指摘頂けない でしょうか? C言語のDLL、作成手順は以下の通りです。 DLL作成環境:Visual C++ 6.0 DLL作成手順----------------------------------------- (1)プロジェクトをDLL用に作る  新規作成→プロジェクト→Win32 Dynamic-Link Library→空のDLLプロジェ クト (2)ファイル追加  ソースファイル+すべてのヘッダファイルを追加 (3)DLLを出力対象の関数に「_declspec(dllexport)」をつける 例)------------------------------------- _declspec(dllexport) short dlltest (char *str1, char *str2) --------------------------------------- (4)char を unsigned char へ変換する(/J コンパイルオプション) (5)プロジェクトをデバッグモードからリリースモードに切り替える (6)ビルド実行 (7)「Release」配下に.dllとlibができる。 -作成手順完----------------------------------------------------- 実際のVBAのDLLの呼び出しは以下の通り行っています。 -AccessVBAにてDLLの宣言及び、呼び出し------------------- '呼び出し宣言 Public Declare Function dlltest _ Lib "C:\Project\Dlltest\Release\dlltest.dll" _ (ByVal st1 As String, _ ByVal st2 As String) As Integer 'DLL呼び出し KEKKA = dlltest(string1, string2) -呼び出し完------------------------------------------------ これで実行するとエラーが返されていまいます。 なにぶん、初心者で今回初めてVBAでのプログラミングを行っているので観点 の抜けなどが多分にあると思われます。 どんな小さなことでもご指摘頂けないでしょうか? 宜しくお願い致します。

  • C#からDLLの呼び出し方

    visual studio 2008 express edition C#3.5 を使用しています。 http://www.hata.cc/docs/wlinee/1.html を参考にC++からではMySub関数を呼び出すことができたのですが、 C#から呼び出そうと次のように記述したのですが、 [System.Runtime.InteropServices.DllImport("a.dll")] extern int WINAPI MySub(int a, int b); 書き終わったときに、MySubの下に赤線がでて「;が必要です」 というエラーが出てしまいます・・・ たぶん「WINAPI」が認識されてないと思うのですが、 どのように記述すればよいのでしょうか? ~C++での記述~ [dllcall.cpp] #include "stdafx.h" #include <windows.h> #include <conio.h>  // getch( ) を使用するのに必要 extern int WINAPI MySub(int a, int b); int _tmain(int argc, _TCHAR* argv[]) { int c; c=MySub(9, 3); printf("ans=%d\n",c); getch();// キーが押されるまで待つ return 0; } [a.cpp] __declspec(dllexport)int WINAPI MySub(int a, int b) { return a-b; }

  • C#でWin32 MFC DLLが呼び出せない

    C#で以下のエラーが発生し、非常に困ってます。 色々とサイトを見たのですが、DLLが本当にないのでは?という意見が多かったです。 しかし、私の方はDLLファイルはbin->debugフォルダ , obj->debugフォルダ、System32に置いてます。 問題が分かる方、是非教えてください! using System.Runtime.InteropServices; namespace WindowsFormsApplication { public partial class Form1 : Form { [DllImport("Win32DLL_TEST.dll")] private extern static int func(int x, int y); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { int n = func3(5, 7);//ここでエラー! } } } エラー内容 'System.DllNotFoundException' のハンドルされていない例外が WindowsFormsApplication.exe で発生しました。 追加情報: DLL 'Win32DLL_TEST.dll' を読み込めません: 指定されたモジュールが見つかりません。 (HRESULT からの例外: 0x8007007E) 備考 DLLは自作のWin32 DLL です。 extern "C"{ __declspec(dllexport) int __cdecl func(int x, int y) } と宣言し、VC++のMFC dialog上では呼び出しを成功しています。

  • C#で、C言語で作ったdllに文字列の参照渡し

    Cで int test(char* moji) {   moji = "test";   return 0; } のようなdllを作り、C#側から   test(ref cs_moji); としても変数cs_mojiに"test"という文字列は帰ってきませんでした。 数時間調べたりしてcs_mojiの型をstringやStringBuilder等としたのですが、どれもうまくいきませんでした。 ポインタのポインタを利用したときは文字列は帰ってきたものの文字化けがたくさんしていて理想とはかけ離れていました。 どのようにしたらCのdllからC#に文字列を送ることができるでしょうか。 初歩的な質問かもしれないですがよろしくお願いいたします。

専門家に質問してみよう