exporting vc++ 2005 class in vba

Hi,

need some help from you guys.

Till now I've been writing dll code in VC++ 6.0 exporting classes to VBA ( Excel ).

I tried to recompile the dll under VC++ 2005 ( I don't get any error message ) but it doesn't work anymore when I call the methods via VBA.

I wonder if anyone has a suggestion on what I should do to make it work properly.

What has changed so radically between VC6.0 and VC2005 that make the code useless

A help would really be appreciated.

Thanks in advance

Christina



Answer this question

exporting vc++ 2005 class in vba

  • Feroz Khan

    Ignore MSJAVA.DLL (I suspect it is there just to annoy java people, it is not really needed). "EFSADU.DLL" I am not familiar with but it is defiantly a suspect. "MSVCR80D.DLL" I completely agree with previous post - do not deploy debug (or as I suspect partially debug in your case) version of anything. Now for the main problem "...tells me Bad dll calling convention ..." without extra info my guesses would be:

    1. You use *.def file to define you exports and it is somehow mismatched (if it is not a secret publish your def file here)

    2. Your VB (VBA) function declaration is wrong. Did you by any chance switched to .Net in your VB part Could you show part of the code (VB) that declares "create_omp"


  • Dilip M

    The original code

    void* __stdcall create_omp() {

    return new Comp_dll; where Comp_dllis the class I want to expose

    }

    void __stdcall destroy_omp( void* objptr ) {

    Comp_dll* ptr = (Comp_dll*) objptr;

    delete ptr;

    ptr = NULL;

    }

    gave me after compiling it in vc++2005 something like "Cannot find dll entry point - error 453"; I changed in:

    extern "C" OMP_DLL_API void* __stdcall create_omp() {

    return new Comp_dll;

    }

    having define OMP_DLL_API as __declspec(dllexport), and worked fine

    extern "C" OMP_DLL_API void destroy_omp( void* objptr ) {

    Comp_dll* ptr = (Comp_dll*) objptr;

    delete ptr;

    ptr = NULL;

    }

    at the contrary tells me Bad dll calling convention ( error 49 ).

    dependency walker show the exports but tells me as well that three dll are missing ( MSVCR80D.DLL, EFSADU.DLL, MSJAVA.DLL ) whereby when I copy MSVCR80D.DLL in the debug directory ( does it make any sense ) it comes up with a CPU type error ( instead of 32 bit show a 64-bit reference ).

    regards

    Christina


  • tnsgod831

    I would have rather prefer to load the VS Project and the Excel Sheet, but I don't know how to attach a zip file.

    Anyway, here is the code

    ####omp_dll.h

    #ifdef OMP_DLL_EXPORTS

    #define OMP_DLL_API __declspec(dllexport)

    #else

    #define OMP_DLL_API __declspec(dllimport)

    #endif

    #include <vector>

    #define STD __stdcall

    using namespace std;

    #pragma warning ( disable : 4251 )

    // This class is exported from the omp_dll.dll

    class OMP_DLL_API Comp_dll

    {

    protected:

    int sz, runs;

    vector<double> vec;

    public:

    Comp_dll();

    virtual ~Comp_dll();

    void set_size( int num );

    void set_runs( int num );

    int iterate();

    };

    ####omp_dll.cpp

    // omp_dll.cpp : Defines the entry point for the DLL application.

    //

    #include "stdafx.h"

    #include "omp_dll.h"

    #ifdef _MANAGED

    #pragma managed(push, off)

    #endif

    BOOL APIENTRY DllMain( HMODULE hModule,

    DWORD ul_reason_for_call,

    LPVOID lpReserved

    )

    {

    switch (ul_reason_for_call)

    {

    case DLL_PROCESS_ATTACH:

    case DLL_THREAD_ATTACH:

    case DLL_THREAD_DETACH:

    case DLL_PROCESS_DETACH:

    break;

    }

    return TRUE;

    }

    #ifdef _MANAGED

    #pragma managed(pop)

    #endif

    // This is the constructor of a class that has been exported.

    // see omp_dll.h for the class definition

    Comp_dll::Comp_dll()

    {

    vec.clear();

    }

    Comp_dll::~Comp_dll()

    {

    }

    void Comp_dll::set_runs( int num )

    {

    runs = num;

    }

    void Comp_dll::set_size( int num )

    {

    sz = num;

    vec.reserve( sz );

    }

    int Comp_dll::iterate()

    {

    for ( int i = 0; i < sz; ++i )

    {

    vec[i] = i;

    }

    return 1;

    }

    // This works!!!!

    extern "C" OMP_DLL_API

    void* create_omp()

    {

    return new Comp_dll;

    }

    // all these don't. I tried with and withoud __stdcall ( in VC++6.0, extern "C" OMP_DLL_API was not necessary )

    extern "C" OMP_DLL_API

    void __stdcall destroy_omp( void* objptr )

    Comp_dll* ptr = (Comp_dll*) objptr;

    if ( ptr != NULL )

    {

    delete ptr;

    ptr = NULL;

    }

    }

    extern "C" OMP_DLL_API

    void o_set_size( void* objptr, int num )

    {

    Comp_dll* ptr = (Comp_dll*) objptr;

    if ( ptr )

    { ptr->set_size( num ); }

    }

    void STD o_set_runs( void* objptr, int num )

    {

    Comp_dll* ptr = (Comp_dll*) objptr;

    if ( ptr )

    { ptr->set_runs( num ); }

    }

    int STD o_iterate( void* objptr )

    {

    Comp_dll* ptr = (Comp_dll*) objptr;

    if ( ptr )

    { return ptr->iterate();}

    return 0;

    }

    ####.def file

    EXPORTS

    create_omp;

    destroy_omp;

    o_set_size;

    o_set_runs;

    o_iterate;

    ###Excel Workbook - VBE

    Declare Function create_omp& Lib "C:\vcpp2005\omp_dll\debug\omp_dll.dll" ()
    Declare Sub destroy_omp Lib "C:\vcpp2005\omp_dll\debug\omp_dll.dll" (ByVal objptr&)
    Declare Sub o_set_size Lib "C:\vcpp2005\omp_dll\debug\omp_dll.dll" (ByVal objptr&, ByVal num&)
    Declare Sub o_set_runs Lib "C:\vcpp2005\omp_dll\debug\omp_dll.dll" (ByVal objptr&, ByVal num&)
    Declare Function o_iterate& Lib "C:\vcpp2005\omp_dll\debug\omp_dll.dll" (ByVal objptr&)

    Sub test()
    Dim ptrOMP&, tm#, k&
    tm = Now
    ptrOMP = create_omp()
    Debug.Print ptrOMP, Hex(ptrOMP)
    ' Call o_set_size(ptrOMP, 1000)
    ' Call o_set_runs(ptrOMP, 1000)
    ' k = o_iterate(ptrOMP)
    Call destroy_omp(ptrOMP)
    MsgBox Format(Now - tm, "hh:mm:ss")

    End Sub

    It is all of my VC++ 20005 class trial

    Christina


  • vicky_dceian

    Usually it doesn't work to just say say things like "doesn't work". It really helps to be more specific.

     chris65 wrote:

    #pragma warning ( disable 4251 )

    I think you don't want to do that. I think you want to fix the problem that is being warned about.

     chris65 wrote:

    // This works!!!!
    extern "C" OMP_DLL_API
    void* create_omp()
    {
    return new Comp_dll;
    }
    

    Except you are probably just ignoring the problem by using "void*". You should use "Comp_dll*" and fix errors that you get from that.

    The above changes might not solve all problems, but I think you need to make those changes regardlous. Then see what other problems remain.



  • chrissav

     chris65 wrote:
    dependency walker show the exports but tells me as well that three dll are missing ( MSVCR80D.DLL, EFSADU.DLL, MSJAVA.DLL ) whereby when I copy MSVCR80D.DLL in the debug directory ( does it make any sense ) it comes up with a CPU type error ( instead of 32 bit show a 64-bit reference ).
    MSVCR80D.DLL is the debugging version and is not redistributable. We are not supposed to copy it to a system that does not have a legal copy of VS. I am not familiar with remote debugging but perhaps you need to use it. Regardlous, don't expect your program to work properly if you simply copy DLLs such as MSVCR80.DLL (the release version) that need to be installed by specialized installation programs. I might be wrong about MSVCR80.DLL, but unless there is documentation saying it can be installed by copying it, we need to install it and other DLLs according to the documentation.

    I don't know what EFSADU.DLL is but unless your application uses Java, it is likely you don't need MSJAVA.DLL.



  • DeborahK

    run depends.exe on it(your dll) see if exports are there. What is an error you are getting on VBA
  • exporting vc++ 2005 class in vba