1

我无法结合 VBA 创建本机 dll 的最小工作示例

存在三个问题:

  • 我无法解决错误 453(找不到 dll 入口点)
  • 我不知道如何编组自耦变压器

VBA (Excel)

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:使用可变参数取得进展。

网上有一个非常有用的网站。

我取得了一些进展,但我仍然无法拨打电话...

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;
}
4

1 回答 1

1

varocarbas给出了一个很好的提示。

我使用Dependency Walker来获取正确的名称。这解决了我的一半问题,我仍然不知道如何编组可变参数

Public Declare Sub CALLADAPTER_SIMPLE _
    Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
    Alias "_simple@0" ()

Public Declare Function CALLADAPTER_ADD _
    Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
    Alias "_add@8" (ByVal A As Integer, ByVal B As Integer) As Integer

Public Declare Sub CALLADAPTER_PRINT _
    Lib "D:\Stackoverflow\Release\CallAdapter.dll" _
    Alias "_print@4" (ByVal FormatSpecifier As String)

只有 ADD 示例是一个很好的示例,因为 stdout 似乎不存在。

于 2013-08-15T15:23:57.047 回答