1

最近友人から入手したc++dllに問題があります。dllをExcelVBAアドインにインポートしようとしています。(私はExcel 2010 32ビットを使用しており、dllはVisual Studio 2008でコンパイルされています)

まず、インポートしようとしましたが、ランタイムエラー49で失敗しました。c++宣言(__stdcal)が欠落していることが原因である可能性があると結論付けました。(ビジュアルスタジオはこれを自動的に行うべきだと思いましたが、大丈夫です)

これで、宣言に__stdcalが含まれる新しいdllが作成されましたが、メソッドは最初にアンダースコア(_)を使用して宣言されています。

したがって、Subを宣言しようとすると、Excelは「無効な文字」のようなものを教えてくれます。C++ファイルを変更せずにこれを回避する可能性はありますか?

'void _SaveFile(const char *FileName_);'
Declare Sub _SaveFile Lib "D:/DLL/TableController.dll" (ByRef FileName_ As String)
            ^
            |

前もって感謝します

これが私の問題の解決につながるかもしれないいくつかの追加情報です。

問題をデバッグするためのc++コードを取得しました...ランタイムエラー49が発生しますが、依存関係ウォーカーによってメソッドの正しい名前が表示されます(これは非常に素晴らしいと思います;))

C#プログラムで同じdllを使用しようとしました。予想通り、完全に正常に動作しました。これが私のC#コードですこれはインポートです:

        [DllImport("JLTable.dll",CallingConvention=CallingConvention.StdCall)]
        internal static extern void JLReadFile(string _FileName);

        [DllImport("JLTable.dll", CallingConvention = CallingConvention.StdCall)]
        internal static extern long JLGetRowCount();

ボタンをクリックするとこれが発生します

        TableRunner.JLReadFile(@"D:\file.tab");
        long rows = TableRunner.JLGetRowCount();
        MessageBox.Show(rows.ToString());

これがVBAの私のコードです宣言:

    Declare Function JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String)
    Declare Function JLGetRowCount Lib "D:/JLTable.dll" () As Long

そして、呼び出し:

    Sub Read()
        Dim path As String
        path = "D:/file.tab"
        JLReadFile (path)
        Dim count As Long
        count = JLGetRowCount()
    End Sub

そして、これが私が呼び出したいc++コードでもあります。何らかの理由で、私の友人はコードが正確に何をしているのかを見せたくありませんが、それでもこのコードと同じように動作します。

.hファイル(JLTable_APIは#define JLTable_API __declspec(dllexport)のようなものです)

    #define STDCALL
    extern "C"
    {
    JLTABLE_API void STDCALL  JLReadFile(const char *FileName_);
    JLTABLE_API void STDCALL  JLSaveFile(const char *FileName_);
    }

.c++ファイル

    void STDCALL  JLReadFile(const char *FileName_)
    {
    //log something to a file
    }
    long STDCALL  JLGetRowCount()
    {
    //log something to a file
    return 0;
    }

私はあなたが私に与えることができるすべてのヒントに非常に感謝しています

そしていつものように事前に感謝します

4

2 に答える 2

3

私は最終的に解決策を持っています。私が間違ったことを教えてくれるブログを見つけました。

http://aandreasen.wordpress.com/2008/05/05/how-to-create-a-dll-for-ms-excel-vba-with-microsoft-visual-c-2008-command-line-tools/

説明したように、正しいメソッド名が必要です。正しいメソッド名を特定するには、依存関係ウォーカーを使用しました。これにより、最終的にこの宣言に至りました

VBA:

Declare Sub JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String) Alias "_JLReadFile@4" (ByRef FileName_ As String)

C++:

void __declspec (dllexport) _stdcall JLReadFile(const char *FileName_);
于 2012-10-19T09:21:17.270 に答える
2

私が実行した同様のテストから、「Alias」キーワードを使用する必要があります。したがって、次のように記述されます。Declare Sub SaveFile Lib "D:/DLL/TableController.dll" Alias "_SaveFile" (ByRef FileName_ As String)

さらに、参照によってファイル名を渡す必要はないと思いますが、間違っている可能性があります。VBを使うのは久しぶりです。ダイナミック ライブラリから関数をインポートする方法の詳細については、このページをご覧ください。

于 2012-10-15T09:51:08.037 に答える