トップ回答者
64ビット環境でExcel VBAからDLLを呼び出す方法

質問
-
お世話になっております。
Visual Studio Premium 2012を使用しています。
Visual C++で作成したDLLファイルをsystem32フォルダーに置き、Excel VBAから呼び出すプログラムを作成しました。
これまで32ビット版Excelでは問題なく動作していましたが、この度、64ビット版Excelに対応するべく試行錯誤していますが、うまくいきません。
構成マネージャーでプラットフォームをx64に変更しましたが解決しませんでした。
ターゲットをAnyCPUにすれば良いと思ったのですが、ターゲットを変更する箇所が見当たりません。
解決につながりそうな情報をお持ちの方がいらっしゃいましたら、回答お願いします。
●動作する環境Win 7 x86 / Excel 2010 x86
Win 7 x64 / Excel 2010 x86
Win 7 x86 / Excel 2013 x86
●動作しない環境Win 7 x64 / Excel 2010 x64
Win 8 x64 / Excel 2013 x64
●dllmain.cpp// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。
#include "stdafx.h"BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
●matrix.cpp#include "stdafx.h"
// 掃き出し
void WINAPI SweepC(long n,long intCs,long intCe,SAFEARRAY **saDat,SAFEARRAY **saRes)
{
long i, j, k, idx[2];
double **dat, **res;// ロック
SafeArrayLock(*saDat);
SafeArrayLock(*saRes);// 配列確保
dat = new double*[n+1];
res = new double*[n+1];
for (i=0;i<=n;i++) dat[i] = new double[n+1];
for (i=0;i<=n;i++) res[i] = new double[n+1];// SAFEARRAY → 2次元データ
for (idx[0] = 1 ; idx[0] <= n ; idx[0]++) {
for (idx[1] = 1 ; idx[1] <= n ; idx[1]++) {
SafeArrayGetElement(*saDat, idx, &dat[idx[0]][idx[1]]);
SafeArrayGetElement(*saRes, idx, &res[idx[0]][idx[1]]);
}
}// 掃き出し
for (i = intCs; i <= intCe; i++) {
if (fabs(dat[i][i]) > 0.0000000001) {
for (j = 1 ; j <= n ; j++) {
for (k = 1 ; k <= n ; k++) {
if (j == i && k == i) {
res[j][k] = 1 / dat[i][i];
} else if (j == i) {
res[j][k] = dat[j][k] / dat[i][i];
} else if (k == i) {
res[j][k] = -dat[j][k] / dat[i][i];
} else {
res[j][k] = dat[j][k] - dat[j][i] * dat[i][k] / dat[i][i];
}
}
}
for (j = 1 ; j <= n ; j++)
for (k = 1 ; k <= n ; k++)
dat[j][k] = res[j][k];
} else {
for (j = 1 ; j <= n ; j++)
for (k = 1 ; k <= n ; k++)
res[j][k] = dat[j][k];
}
}// 2次元データ → SAFEARRAY
for (idx[0] = 1 ; idx[0] <= n ; idx[0]++) {
for (idx[1] = 1 ; idx[1] <= n ; idx[1]++) {
SafeArrayPutElement(*saDat, idx, &dat[idx[0]][idx[1]]);
SafeArrayPutElement(*saRes, idx, &res[idx[0]][idx[1]]);
}
}// ロック解除
SafeArrayUnlock(*saDat);
SafeArrayUnlock(*saRes);// 配列解放
for (i=0;i<=n;i++) delete dat[i];
for (i=0;i<=n;i++) delete res[i];
delete dat;
delete res;return;
}
●define,defLIBRARY "mydll"
EXPORTS
SweepC
●stdafx.h// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Windows ヘッダーから使用されていない部分を除外します。
// Windows ヘッダー ファイル:
#include <windows.h>// TODO: プログラムに必要な追加ヘッダーをここで参照してください。
#define _USE_MATH_DEFINES
#include "math.h" //数学関数
#include "oleauto.h" //SAFEARRAY
●targetver.h#pragma once
// 以下のマクロは、最低限必要なプラットフォームを定義します。最低限必要なプラットフォームとは、
// アプリケーションを実行するために必要な機能を備えた最も古いバージョンの Windows や Internet Explorer など
// をいいます。これらのマクロは、指定したバージョンと、それ以前のバージョンのプラットフォーム上で利用できるすべての機能を有効にすることによって
// 動作します。// 下で指定された定義の前に対象プラットフォームを指定しなければならない場合、以下の定義を変更してください。
// 異なるプラットフォームに対応する値に関する最新情報については、MSDN を参照してください。
#ifndef WINVER // 最低限必要なプラットフォームが Windows Vista であることを指定します。
#define WINVER 0x0600 // これを Windows の他のバージョン向けに適切な値に変更してください。
#endif#ifndef _WIN32_WINNT // 最低限必要なプラットフォームが Windows Vista であることを指定します。
#define _WIN32_WINNT 0x0600 // これを Windows の他のバージョン向けに適切な値に変更してください。
#endif#ifndef _WIN32_WINDOWS // 最低限必要なプラットフォームが Windows 98 であることを指定します。
#define _WIN32_WINDOWS 0x0410 // これを Windows Me またはそれ以降のバージョン向けに適切な値に変更してください。
#endif#ifndef _WIN32_IE // 最低限必要なプラットフォームが Internet Explorer 7.0 であることを指定します。
#define _WIN32_IE 0x0700 // これを IE の他のバージョン向けに適切な値に変更してください。
#endif●64ビット用VBAのコード
Private Declare PtrSafe Sub SweepC Lib "mydll.dll" (ByVal n As Long, ByVal s As Long, ByVal e As Long, ByRef dat() As Double, ByRef res() As Double)
Private Sub MatSweep(n As Integer, s As Integer, e As Integer, adbDat() As Double, adbRes() As Double)
SweepC n, s, e, adbDat(), adbRes() 'この行でエラーが表示される
End Sub
●VBAで表示されるエラーの内容実行時エラー '53':ファイルが見つかりません mydll.dll
回答
すべての返信
-
では逆の可能性として、64bit環境であってもインストールしたExcelが実は32bit版ということはありますでしょうか? Excelを起動してタスクマネージャで確認した際に (32ビット) 等の表示が出ていないか確認してください。
ちなみに64 ビット版の Office 2010 をインストールする方法には
64 ビット OS に Office 2010 のインストール DVD-ROM をセットした場合、既定では 32 ビット版 Office 2010 のインストーラーが起動します。これは、64 ビット OS 環境に対しても 32 ビット版 Office 2010 をインストールすることが推奨されているためです。
と書かれています。
-
ご連絡ありがとうございます。
こちらのダウンロードとインストールのことでしょうか?
http://www.microsoft.com/ja-jp/download/details.aspx?id=30679