barus's diary

とても真面目なblogですにゃ

コマンドラインでC#からVC++作成のDLLを使用 for VS2015 Express for Desktop

 

金融工学のエッセンス: 難関ブラック・ショールズを見える化する 動的視覚化シリーズ

金融工学のエッセンス: 難関ブラック・ショールズを見える化する 動的視覚化シリーズ

 

 

 

C#からVC++作成のDLLを呼び出しするサンプルプログラム

 

※開発環境を整えるには、

 

Windowsアプリを作成してみよう for VS2015 Express for Desktop C#
を参考に、VS2015をインストールして下さい。

 

「開発者コマンド プロント for VS2015」を起動します。

mydll.cpp
Program.cs

を作成します。

 

mydll.cpp


#include <string.h>
#include <iostream>
 
#ifdef __cplusplus
#define DLLEXPORT extern "C" __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllexport)
#endif
 
using namespace std; 
 
 //整数値を返す
 DLLEXPORT int  add(int a, int b) {
    return a + b;
 }
 
 //文字列の参照値渡し
 DLLEXPORT void  test_str(char *str)
 {
   sprintf(str, "%sだにゃん♪", str);
 }

 

Program.cs

 

 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
// DllImportに必要
using System.Runtime.InteropServices;
 
namespace Usemydll
{
    class Program
    {
        [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
        private extern static int add(int a, int b);
        
        [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
        private extern static void test_str(StringBuilder str);
        
        static void Main(string[] args)
        {
            int result = add(10, 3);
            Console.WriteLine("dll add = {0}" ,result);
            
            StringBuilder buff = new StringBuilder();
            buff.Append("C#からの文字列");
            test_str(buff);
            Console.WriteLine("dll test_str = {0}", buff);
 
        }
        
    }
}
 

 

え~。よくわからにゃいのが

StringBuilder クラス

ですね。マイクロソフトのページによる説明だと

StringBuilder は、カプセル化する文字列内の文字数を拡張できるように
する動的オブジェクトですが、保持可能な最大文字数の値を指定することができます。
この値を、オブジェクトの容量と呼びます。これを現行の StringBuilder が保持する
文字列の長さと混同すべきではありません。 たとえば、"Hello" という長さ 5 の
文字列を持つ StringBuilder クラスの新しいインスタンスを作成するときに、
オブジェクトの最大容量として 25 を指定することができます。

StringBuilder を変更する際、容量に達するまでは、自動再割り当ては発生しません。
容量に達すると、新しい領域が自動的に割り当てられ、容量が 2 倍になります。
オーバーロードされたコンストラクターのいずれかを使用して、
StringBuilder クラスの容量を指定することができます。
次の例は、MyStringBuilder オブジェクトを最大 25 の領域に拡張できることを示しています。


なんか、他に記述の仕方があるのかググったのですが、
どうもなさそうなので、C#ではこれを使えばいいと、理解しました・・。

>cl mydll.cpp /LD /EHsc

コンパイルします。/LDはDLLを作る際のオプション。/EHscはC++ 例外処理を使う際は
使用しろよゴルァとコンパイルする際に怒られるのでつけています。

うまくいくと、mydll.dll ファイルが作成されます。

次にこれを呼び出すC#側のコンパイルをします。

>csc Program.cs

Program.exeファイルが出来ましたら、実行させてみましょう。

>Program.exe
dll add = 13
dll test_str = C#からの文字列だにゃん♪
と出たら成功です。

 

f:id:hatakeka:20160912120948p:plain

 


えーと、うまくいかない人がいるかと思います。
恐らく、うまく成功した方は32Bitマシンかと思います。

実は、64Bitマシンではコンパイルが通ってもエラーが起きる場合があります。

なので、64Bitマシンの場合
コンパイルの際にちょっとしたおまじないが必要となります。

プロント画面で cl を叩いてみてください。

S:\plog>cl
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24213.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.


もし for x86 になっていたら32Bit用にコンパイルするよって意味です。
これを、64Bitように変更するには
コマンドラインHello World! for VS2015 VC++
でインストールした際に、vcvarsall.batファイルがインストールされているので
これを利用します。

S:\plog>"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64

vcvarsall.batを直接呼び出しています。
こうすると、cl を実行すると

S:\plog>cl
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24213.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
となり、x86からx64に変わった事がわかります。

f:id:hatakeka:20160912121053p:plain

 

上記は、x86からx64の切り替えの様子です。


以下マイクロソフトの引用

vcvarsall.bat を実行して 64 ビット ツールセットを使用するには
コマンド プロンプトで、Visual C++ インストール ディレクトリに変更します
(システムおよび Visual Studio のインストールによって異なりますが、
一般的な場所は C:\Program Files (x86)\Microsoft Visual Studio version\VC\ です)。
たとえば、次のように入力します。

cd "\Program Files (x86)\Microsoft Visual Studio 12.0\VC"

x64 プラットフォームを対象とする 64 ビット コマンドライン ビルドの
コマンド プロンプト ウィンドウを設定するには、コマンド プロンプトで
次のように入力します。
vcvarsall amd64

x86 プラットフォームを対象とする 64 ビット コマンドライン ビルドの
コマンド プロンプト ウィンドウを設定するには、コマンド プロンプトで
次のように入力します。
vcvarsall amd64_x86

ARM プラットフォームを対象とする 64 ビット コマンドライン ビルドの
コマンド プロンプト ウィンドウを設定するには、コマンド プロンプトで
次のように入力します。
vcvarsall amd64_arm

 

 

 

終わり。

 

 



 


人工知能が金融を支配する日

人工知能が金融を支配する日