1

I am unable to create a minimal working example of a native dll in combination with VBA

There are three Problems:

  • I can not resolve error 453 (can't find dll entry point)
  • I do not know how to marshall variac

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

Edit #1: I completely reworked the examples to better illustrate my problems.


Edit #2: Progress with variadic.

There is a very useful site on the web.

I made some progress but i stll can not compule the call...

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

Ansi 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;
}
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
Johannes
  • 6,490
  • 10
  • 59
  • 108
  • 1
    The error information in MSDN sounds pretty descriptive: http://msdn.microsoft.com/en-us/library/aa445593(v=vs.60).aspx Follow the recommendations there. Also next time, please, include the error message in your question. – varocarbas Aug 15 '13 at 10:12
  • I am unable to apply that information. – Johannes Aug 15 '13 at 15:11
  • 1
    If the first option (quick look at MSDN info) does not solve your problem; you might give a chance to the second option (quick research): http://stackoverflow.com/questions/6340041/using-a-c-sharp-dll-inside-excel-vba. – varocarbas Aug 15 '13 at 15:20
  • 1
    PS: you shouldn't find any problem to adapt these C# ideas; in any case, you might do a more intense research by your own. I am not in a position to answer this question and that's why I didn't do it. The reason why I wrote this comment was to highlight that your original question wasn't too descriptive. – varocarbas Aug 15 '13 at 15:24

1 Answers1

1

varocarbas gave a good hint.

I used Dependency Walker to get the correct names. This solves half of my problem, i still dont know how to marshall variadic

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)

Only the ADD example is a good example since stdout does not seem to exist.

Community
  • 1
  • 1
Johannes
  • 6,490
  • 10
  • 59
  • 108