【问题标题】:Calling Native C from VBA从 VBA 调用本机 C
【发布时间】:2013-08-16 00:10:30
【问题描述】:

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

网上有一个very useful site

我取得了一些进展,但我仍然无法调用...

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

【问题讨论】:

  • MSDN 中的错误信息听起来非常具有描述性:msdn.microsoft.com/en-us/library/aa445593(v=vs.60).aspx 遵循那里的建议。下次,请在您的问题中包含错误消息。
  • 我无法应用该信息。
  • 如果第一个选项(快速查看 MSDN 信息)不能解决您的问题;您可能会给第二个选项一个机会(快速研究):stackoverflow.com/questions/6340041/….
  • PS:你不应该发现任何问题来适应这些 C# 想法;无论如何,您可以自己进行更深入的研究。我无法回答这个问题,这就是我没有回答的原因。我写此评论的原因是为了强调您最初的问题不是太具有描述性。

标签: vba ansi


【解决方案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 示例是一个很好的示例,因为标准输出似乎不存在。

【讨论】:

    猜你喜欢
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 2014-01-27
    • 2017-05-17
    • 1970-01-01
    相关资源
    最近更新 更多