[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to create a C++ wrapper DLL to expose functions from a C++ .lib and .h (header) file?

Posted on 2007-08-03
15
Medium Priority
?
8,728 Views
Last Modified: 2013-11-05
A hardware manufacturer has provided me with a .lib and header file to allow me to directly access some functions provided by their drivers. I have very limited C++ experience and have the bulk of a program I was going to use to control the driver written in VB.NET. I know that I cannot access the .lib file directly from VB.NET. I have to write a DLL in C++ to wrap the functions, constants, and structures that are exposed by the .lib file to make them available to a .NET application.

Again, I'm a real newbie with C++. I have found a couple of posts on how to this but not a set by step how to. I have gotten as far as the following steps:
 - I Created a new Win32 C++ Project.
 - Entered a Project name and in the new App Wizard popup, selected:
      * Application type: DLL
      * Additional options: Export symbols
 - Clicked on Finish.

I know this isn't much. I know I have to link to the header file and the .lib file somehow. Then write functions to expose the .lib functions. Ideally I would like to expose the constants and structure that are detailed in the header file as well. I would like the new wrapper DLL to be reference as a COM object in VB.NET so that I can take advantage of intellisense and not have to worry about creating correct DllImport functions.

Please provide code example for the functions, constants, and structures. I can provide example functions, constants, and structures from the header file if it helps.
0
Comment
Question by:xAragornx
  • 8
  • 6
15 Comments
 
LVL 13

Accepted Solution

by:
Mark_FreeSoftware earned 1800 total points
ID: 19624842

when the functions from the drivers are in a header and a .lib, this means you are interfacing a dll, right?

if thats the case, you should be able to convert those header declarations to visual basic api syntax
so you can interface with it as the normal windows api
0
 

Author Comment

by:xAragornx
ID: 19624864
I was thinking that as well but I don't know what DLL it is interfacing with. How would I find that out?
0
 
LVL 13

Assisted Solution

by:Mark_FreeSoftware
Mark_FreeSoftware earned 1800 total points
ID: 19624881

the name of the .lib is likely the name of the dll
0
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19624886
do you know how to convert c++ declarations to vb declarations?
0
 

Author Comment

by:xAragornx
ID: 19625005
OK found it. You are right. It is the same name as the .lib file.

I'm not that great at converting the declarations from C++ so any help you can provide would be great. I know how to declare the constants. The structers and the functions are more tricky. I will call NVAPI_GetView first and then NVAPI_SetView if needed. So I don't think I need to call NvAPI_EnumNVidiaDisplayHandle() as I will use the info I get from NVAPI_GetView. Here are the functions I need to access from managed vb.net code:

///////////////////////////////////////////////////////////////////////////////
// FUNCTION NAME:   NvAPI_SetView
//
// DESCRIPTION:     This API lets caller to modify target display arrangement for selected source display handle in any of the nview modes.
//                  It also allows to modify or extend the source display in dualview mode.
//
// PARAMETERS:      hNvDisplay(IN) - NVIDIA Display selection. NVAPI_DEFAULT_HANDLE not allowed, it has to be a handle enumerated with NvAPI_EnumNVidiaDisplayHandle().
//                  pTargetInfo(IN) - Pointer to array of NV_VIEW_TARGET_INFO, specifying device properties in this view.
//                                    The first device entry in the array is the physical primary.
//                                    The device entry with the lowest source id is the desktop primary.
//                  targetCount(IN) - Count of target devices specified in pTargetInfo.
//                  targetView(IN) - Target view selected from NV_TARGET_VIEW_MODE.
//
// RETURN STATUS:
//                  NVAPI_OK - completed request
//                  NVAPI_ERROR - miscellaneous error occurred
//                  NVAPI_INVALID_ARGUMENT: Invalid input parameter.
//
///////////////////////////////////////////////////////////////////////////////

typedef struct
{
    NvU32 version;     // (IN) structure version
    NvU32 count;       // (IN) target count
    struct
    {
        NvU32 deviceMask;    // (IN/OUT) device mask
        NvU32 sourceId;      // (IN/OUT) source id
        NvU32 bPrimary:1;    // (OUT) Indicates if this is the desktop primary
        NvU32 bInterlaced:1; // (OUT) Indicates if the timing being used on this monitor is interlaced
        NvU32 bGDIPrimary:1;// (IN/OUT) Indicates if this is the desktop GDI primary.
    } target[NVAPI_MAX_VIEW_TARGET];
} NV_VIEW_TARGET_INFO;

#define NV_VIEW_TARGET_INFO_VER  MAKE_NVAPI_VERSION(NV_VIEW_TARGET_INFO,2)

NVAPI_INTERFACE NvAPI_SetView(NvDisplayHandle hNvDisplay, NV_VIEW_TARGET_INFO *pTargetInfo, NV_TARGET_VIEW_MODE targetView);

///////////////////////////////////////////////////////////////////////////////
// FUNCTION NAME:   NvAPI_GetView
//
// DESCRIPTION:     This API lets caller retrieve the target display arrangement for selected source display handle.
//
// PARAMETERS:      hNvDisplay(IN) - NVIDIA Display selection. NVAPI_DEFAULT_HANDLE not allowed, it has to be a handle enumerated with NvAPI_EnumNVidiaDisplayHandle().
//                  pTargetInfo(OUT) - User allocated storage to retrieve an array of  NV_VIEW_TARGET_INFO. Can be NULL to retrieve the targetCount.
//                  targetMaskCount(IN/OUT) - Count of target device mask specified in pTargetMask.
//                  targetView(OUT) - Target view selected from NV_TARGET_VIEW_MODE.
//
// RETURN STATUS:
//                  NVAPI_OK - completed request
//                  NVAPI_ERROR - miscellaneous error occurred
//                  NVAPI_INVALID_ARGUMENT: Invalid input parameter.
//
///////////////////////////////////////////////////////////////////////////////
NVAPI_INTERFACE NvAPI_GetView(NvDisplayHandle hNvDisplay, NV_VIEW_TARGET_INFO *pTargets, NvU32 *pTargetMaskCount, NV_TARGET_VIEW_MODE *pTargetView);
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 200 total points
ID: 19625019
What you would do is providing call stubs from your DLL that then are accessible via PInvoke, e.g.

//wrapper.cpp
#include "manufacturer.h"
#pragma comment(lib,"manufacturer.lib")

extern "C" __declspec(dllexport) int WrapperCallManufacturerFunc1(int a, int b)
{
    return ManufacturerFunc1(a,b);
}

extern "C" __declspec(dllexport) char* WrapperCallManufacturerFunc2(char* pString)
{
    return ManufacturerFunc2(pString);
}

extern "C" __declspec(dllexport) double WrapperCallManufacturerFunc3(double d)
{
    return ManufacturerFunc3(d);
}

extern "C" __declspec(dllexport) void WrapperCallManufacturerFunc4()
{
    ManufacturerFunc4();
}

That's basically it. The 'extern "C"' statement is used to tell the compiler to not apply C++ name mangling, i.e. the functions names are not decorated and exported 'as is'. The return types resemble the return types of the functions in the .lib you want to call, except for 'void' functions where your function is 'void' also, yet the 'return' statement is not used. Then you can access the wrapper functions like

Declare Auto Function ManufacturerFunc1  Lib "wrapper.dll" Alias "WrapperCallManufacturerFunc1 " ( _
    ByVal a As Integer, _
    ByVal b As Integer) _
    As Integer

or

Imports System.Runtime.InteropServices
Public Class Win32
    Declare Auto Function WrapperCallManufacturerFunc1 Lib "wrapper.dll" _
       (ByVal a As Integer, _
        ByVal b As Integer) As Integer
End Class

See also http://msdn2.microsoft.com/en-us/library/172wfck9(vs.80).aspx ("Walkthrough: Calling Windows APIs") and http://msdn2.microsoft.com/en-us/library/w4byd5y4(VS.80).aspx ("Creating Prototypes in Managed Code")
0
 
LVL 13

Assisted Solution

by:Mark_FreeSoftware
Mark_FreeSoftware earned 1800 total points
ID: 19625509
Structure NvU32
        Dim ii As Integer
    End Structure

    Structure target
        Dim deviceMask As NvU32
        Dim sourceId As NvU32
        Dim bPrimary As NvU32
        Dim bInterlaced As NvU32
        Dim bGDIPrimary As NvU32
    End Structure

    Structure NV_VIEW_TARGET_INFO
        Dim version As NvU32
        Dim count As NvU32
        Dim targets() As target
    End Structure

    Dim a1 As NV_VIEW_TARGET_INFO

and do not forget to redim the a1.targets!!!!!!!!


i did fill in a random number for NV_VIEW_TARGET_INFO,
and i dont know what NvU32 is either
0
 

Author Comment

by:xAragornx
ID: 19625549
Mark,

Thanks for the Info. I think I can map the stuff myself. It's not as hard as I thought. Your example above is good enough to get me started.

JKR,

Thanks for you info as well. I going to call the DLL directly instead. I didn't realize that the DLL was available.
0
 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19625724

thanks for the points and the a- grade!


also remember when converting arrays from c to vb:

a c array
arrayname[20]
creates an array with 20 items,
a vb array
arrayname(20)
creates an array from 0-20, thus 21 items!!!!
0
 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19625732
atleast, vb6 but i dont think they changed that in vb.net
0
 

Author Comment

by:xAragornx
ID: 19625973
It seems that the DLL file does not expose the functions listed in the header file. I used dependency walker to see what functions were exposed and the only ones where the following:
- NVAPI_QueryInterface
- DllCanUnloadNow
- DllGetClassObject
- DllRegisterServer
- DllUnRegisterServer

VB.NET tells me that it can't find the entrypoint for the function I'm calling. I think I missing something or maybe I can't call these functions directly from my .net app to the DLL.
0
 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19626585

if you look in dependency walker, does any of the other NV dlls export one of these functions?

could be that the lib just redirects the functions to another dll
0
 

Author Comment

by:xAragornx
ID: 19626933
I checked all the NV DLL I could find but none of them expose the functions. Could the functions be hiding behind the NVAPI_Queryinterface. I also opened the .lib file in a HEX editor and the only reference I found was to the NVAPI.DLL Queryinterface. My programing knowledge is limited so please forgive me if my "stab in the dark" is completely rediculous.
0
 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19627679
yeah, it could be that the NVAPI_Queryinterface is returning some sort of struct that contains the real functions,
i looked with depends trough all nv* dlls, but i cant seem to find those functions.

think you are back to a proxy dll then
0
 

Author Comment

by:xAragornx
ID: 19627886
Rats! Could you give me one example on how to map on of the functions I outlined above? jkr was nice enough to give me a baseline but the structures complicate things and I'm not sure how to do it.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question