dポイントプレゼントキャンペーン実施中!

vc++2008 expressを使用しています。

http://msdn.microsoft.com/ja-jp/library/ms235636 …
参考にdllを作成しました。

http://q.hatena.ne.jp/1308476017を参考にすると、上記で作成したdllは
Win32 DLLだと思われます。

でこの作成したdllをvbaで使用したいです。
以下はそのソースです。


dllのソースです。
###MathFuncsDll.h

namespace MathFuncs
{

extern "C"
{
class MyMathFuncs
{
public:
// Returns a + b
__declspec(dllexport) double __stdcall Add(double a, double b);

// Returns a - b
__declspec(dllexport) double __stdcall Subtract(double a, double b);

// Returns a * b
__declspec(dllexport) double __stdcall Multiply(double a, double b);

// Returns a / b
// Throws DivideByZeroException if b is 0
__declspec(dllexport) double __stdcall Divide(double a, double b);
};
}
}

###MathFuncsDll.cpp
#include "MathFuncsDll.h"

using namespace std;

namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b)
{
return a + b;
}

double MyMathFuncs::Subtract(double a, double b)
{
return a - b;
}

double MyMathFuncs::Multiply(double a, double b)
{
return a * b;
}

double MyMathFuncs::Divide(double a, double b)
{

return a / b;
}
}


vbaのソース
Private Declare Function Add Lib "C:\DLL_create\DynamicLibrary\Debug\MathFuncsDll.dll" Alias "?Add@MyMathFuncs@MathFuncs@@QAGNNN@Z" _
(ByVal int1 As Double, ByVal int2 As Double) As Double



Private Sub CommandButton1_Click()

Dim a As Double

a = Add(5, 2)


End Sub

Alias "?Add@MyMathFuncs@MathFuncs@@QAGNNN@Z"の箇所は
dependency walkerで調べました。

これを実行すると、「実行時エラー49 DLLが正しく呼び出せません。」
というエラーがでます。
どうすれば実行できるのかご教授ください。

A 回答 (4件)

C++側は、akinomyogaさんの


> __declspec(dllexport) の前に static が抜けているだけでは?
で。

VBA側
Private Declare PtrSafe Function Add Lib "MathFuncsDll.dll" _
Alias "?Add@MyMathFuncs@MathFuncs@@SANNN@Z" _
(ByVal int1 As Double, ByVal int2 As Double) As Double

Sub hoge()
Dim a As Double
ChDrive ThisWorkbook.Path
ChDir ThisWorkbook.Path
a = Add(5, 2)
MsgBox a
End Sub

修飾名は dumpbin /exports で確認。
    • good
    • 0
この回答へのお礼

返事が遅くなりすみません、ご回答ありがとうございます。
C++側でstaticをつけて、vba側はdllをフルパス指定すると
正しくうごきました。
No3さんの方も試してみたいと思います。

ちなみにhttp://www2.odn.ne.jp/sailing/exceldll.htmでも
動きました。
ありがとうございました。

お礼日時:2013/11/08 09:12

__declspec(dllexport) の前に static が抜けているだけでは? (あと、static を追加すると Alias で指定している C++ 名前修飾も変わります。

)

しかし、(色々と事情はあるのかも知れませんが) そもそもの問題として、クラスの静的メンバ関数として関数を公開する意味はあるのでしょうか。C++ から使う為の DLL の場合にはそれも意味があると思いますが、VBA などから利用するのであれば C++ のクラスの中で定義する意味はありません。namespace や class の中ではなくて、単にグローバルに関数を書き連ねた方が分かりやすいと思います。

もし DLL を C++ と VBA の両方から使いたいのだとしても、VBA の為にグローバルに

extern "C" __declspec(dllexport) double __stdcall Add(double a, double b) { return MathFuncs::MyMathFuncs::Add(a,b); }

という感じに中継する関数を定義した方が、わざわざ depends などでシンボルを調べて Alias に指定しなくても良いし、管理も楽な気がします。


# 所で、インスタンスメンバ関数に __stdcall をつけるとどうなるのかと思って調べてみたら、第一引数に this ポインタを受け取って、第二引数以降に元々の引数を受け取るというのを __stdcall 呼出既約で行う様になるのですね。
    • good
    • 0
この回答へのお礼

返事が遅くなりすみません、ご回答ありがとうございます。
C++側でstaticをつけて、vba側はdllをフルパス指定すると
正しくうごきました。
No3さんの方も試してみたいと思います。

ちなみにhttp://www2.odn.ne.jp/sailing/exceldll.htmでも
動きました。
ありがとうございました。

お礼日時:2013/11/08 09:11

このdllコンパイルできるの?


C++クラスをextern "C"できるとは思えないんですけど。
namespaceにも入っているし・・・

extern "C"ってCの関数として(Cの名前規約で)公開するっていうことだから
Cで書けないインタフェースを使っちゃだめでしょ。
    • good
    • 0

VBAからの呼び出し方はわかりませんが、double MyMathFuncs::Add(double a, double b)と他の3つのメソッドはインスタンスメソッドとして定義されていますから、インスタンスなしでは呼び出せないです。

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!