LoginSignup
0
3

More than 5 years have passed since last update.

VC++でDLLを作りC#から利用

Last updated at Posted at 2018-09-10

参考:C#からC/C++の関数をコールする方法 まとめ①

Visual Studio Community 2017を起動する。
メニューから[ファイル]->[新規作成]->[プロジェクト]を選択する。
[Visual C++/空のプロジェクト]を選択し、適当な名前を付ける。(例:dlltest

メニューから[プロジェクト]->[新しい項目の追加]を選択する。
[C++ファイル(.cpp)]を選択し、適当な名前を付ける。(例:dlltest

dlltest.cpp
#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int __stdcall add(int a, int b)
{
    return a + b;
}

DLLEXPORT int __stdcall sub(int a, int b)
{
    return a - b;
}

ツールバーの[ソリューション構成]をReleaseにする。
image.png

メニューから[プロジェクト]->[dlltestのプロパティ]を選択する。
[構成プロパティ/全般]を選択し、[プロジェクトの既定値/構成の種類]を[ダイナミック ライブラリ (.dll)]にする。
image.png

メニューから[ビルド]->[ソリューションのビルド]を選択する。(もしくはCtrl+Shift+B)
Release/dlltest.dllを任意のディレクトリにコピーする。

dev.bat
@echo off
path %path%;C:\Windows\Microsoft.NET\Framework\v4.0.30319
cmd
asssub.cs
// csc /platform:x86 addsub.cs

using System;
using System.Runtime.InteropServices;

class Program {
    [DllImport("dlltest.dll")]
    private extern static int add(int a, int b);
    [DllImport("dlltest.dll")]
    private extern static int sub(int a, int b);

    static void Main() {
        Console.WriteLine("add = {0}", add(1, 2));
        Console.WriteLine("sub = {0}", sub(1, 2));
    }
}

image.png

/platformオプションを指定しないと64bit dllを読み込もうとするようだ。

ハンドルされていない例外: System.BadImageFormatException: 間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外:0x8007000B)
   場所 Program.add(Int32 a, Int32 b)
   場所 Program.Main()

64bit版のcsc.exeでコンパイルすると警告は出るが実行は可能。

warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Data.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Data.OracleClient.dll' は異なるプロセッサを対象にしています。warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.EnterpriseServices.dll'
        は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Transactions.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Web.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'mscorlib.dll' は異なるプロセッサを対象にしています。

[ソリューション プラットフォーム]を[x64]にして64bit dllを作れば/platformオプションなしでも実行可能。
image.png

.defファイルでexportする方法もある。

dlltest.cpp
int __stdcall add(int a, int b)
{
    return a + b;
}

int __stdcall sub(int a, int b)
{
    return a - b;
}
dlltest.def
EXPORTS
    add
    sub
0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3