VBA と組み合わせたネイティブ dll の最小限の動作例を作成できません
次の 3 つの問題があります。
- エラー 453 を解決できません (dll エントリ ポイントが見つかりません)
- バリアックをマーシャリングする方法がわかりません
VBA (エクセル)
Option Explicit
Public Declare Sub KERNEL32_SLEEP _
Lib "kernel32" _
Alias "Sleep" (ByVal dwMilliseconds As Long)
Public Declare Sub CALLADAPTER_SIMPLE _
Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
Alias "simple" ()
Public Declare Function CALLADAPTER_ADD _
Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
Alias "add" (ByVal A As Integer, ByVal B As Integer) As Integer
Public Declare Sub CALLADAPTER_PRINT _
Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
Alias "print" (ByVal FormatSpecifier As String)
Sub TEST_KERNEL32_SLEEP()
Call KERNEL32_SLEEP(2000) 'works
End Sub
Sub TEST_CALLADAPTER_SIMPLE()
Call CALLADAPTER_SIMPLE 'error 453 can't find dll entry point
End Sub
Sub TEST_CALLADAPTER_ADD()
Dim A, B, C As Integer
A = 30
B = 12
C = CALLADAPTER_ADD(A, B) 'error 453 can't find dll entry point
MsgBox "A + B = " & C
End Sub
Sub TEST_CALLADAPTER_PRINT()
Call CALLADAPTER_PRINT("Hello World") 'error 453 can't find dll entry point
End Sub
Sub TEST_CALLADAPTER_PRINTF()
'I do not know how to marshall variadic
End Sub
Ansi C (Visual Studio 2010)
// Header
#ifdef CALLADAPTER_EXPORTS
#define CALLADAPTER_API __declspec(dllexport)
#else
#define CALLADAPTER_API __declspec(dllimport)
#endif
CALLADAPTER_API void _stdcall simple( void );
CALLADAPTER_API int _stdcall add( int a, int b );
CALLADAPTER_API void _stdcall print( const char * msg );
CALLADAPTER_API int _stdcall printf( const char * format, ... );
// code
#include "CallAdapter.h"
#include <stdio.h>
#include <stdarg.h>
CALLADAPTER_API void _stdcall simple( void )
{
printf("simple was called\n");
}
CALLADAPTER_API int _stdcall add( int a, int b )
{
return a + b;
}
CALLADAPTER_API void _stdcall print( const char * msg )
{
printf( "%s", msg );
}
CALLADAPTER_API int _stdcall printf( const char * format, ... )
{
int ret;
va_list args;
va_start( args, format );
ret = vprintf( format, args );
va_end( args );
return ret;
}
編集#1:問題をよりよく説明するために、例を完全に作り直しました。
編集 #2: variadic で進行します。
ウェブ上に非常に便利なサイトがあります。
私はいくつかの進歩を遂げましたが、まだ呼び出しを完了できません...
VBA
Option Explicit
Public Declare Function CallAdapter_sprintf _
Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
Alias "sprintf" (ByRef DST As String, ByRef FORMAT As String, ParamArray args()) As Integer
Sub TEST_CALLADAPTER_sprintf()
Dim DESTINATION, FORMAT As String
Dim OTHER() As Variant
Dim C As Integer
FORMAT = "%s"
OTHER = Array("Hello World")
DESTINATION = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
C = CallAdapter_sprintf(DESTINATION, FORMAT, OTHER)
MsgBox "RET " & C & " -> " & DESTINATION
End Sub
アンシ C
CALLADAPTER_API int _stdcall sprintf( char * dest, const char * format, ... )
{
int ret;
va_list args;
va_start( args, format );
ret = vsprintf( dest, format, args );
va_end( args );
return ret;
}