[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How do I import an external library .lib written in C. Please note I do have access to the C source code.

Posted on 2008-11-16
16
Medium Priority
?
575 Views
Last Modified: 2013-12-17
How do I import an external library .lib written in C.

Please note I do have access to the C source code. I was able to compile the .LIb files using C++ Visual Studio 2005.

Is there a way to produce a .dll from the source so that my C# program can reference it?
0
Comment
Question by:Rosman10
  • 9
  • 7
16 Comments
 
LVL 7

Expert Comment

by:psdavis
ID: 22973545
Absolutely.  
Just create yourself a DLL filled with simple method calls to the .lib file.   Make sure that you _dllexport all of your methods to make them visible.
Then just P/Invoke into the DLL as normal.
0
 

Author Comment

by:Rosman10
ID: 22973557
Glad to know that it can be done.

Can you point me somewhere where there is an examle to create -
"DLL filled with simple method calls to the .lib file.   Make sure that you _dllexport all of your methods to make them visible".


0
 
LVL 7

Expert Comment

by:psdavis
ID: 22975415
Let me get to work in about 4 hours and I'll post code I used.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 7

Expert Comment

by:psdavis
ID: 22976154
Ok, found it.
The code is just going to have a header and little wrappers into the methods.
Then have a .def file that defines your exported methods
Include your .lib function into the solution, build yourself a .DLL, and PInvoke.

// IrisSnap.cpp : Defines the entry point for the DLL application.
//
 
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
 
#include "Mirlin.h"
#include "BioMatch.h"
#include "cmtiris.h"
#include "CSmartSensors.h"
 
#ifdef _MANAGED
#pragma managed(push, off)
#endif
 
BOOL APIENTRY DllMain( HMODULE,
                       DWORD  ul_reason_for_call,
                       LPVOID )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
 
CSmartSensors::CSmartSensors( )
{
    return;
}
 
MIRLIN_API int __stdcall GetEnrolTemplate_Standard( UINT8 *pImage, UINT32 ImageWidth, UINT32 ImageHeight,MIR_TEMPLATE *pEnrolTemplate, MIR_DIAGNOSTICS *pDiagnostics, UINT8 *pNormImage, UINT32 NormWidth, UINT32 NormHeight,UINT8 *pLocalisedImage )
{
   return MIR_GetEnrolTemplate( pImage, ImageWidth, ImageHeight,pEnrolTemplate, pDiagnostics,pNormImage, NormWidth, NormHeight,pLocalisedImage);
}
 
------
Smartsensors.def
 
LIBRARY	"SmartSensors.Library.dll"
 
; Explicit exports can go here
EXPORTS
 
GetEnrolTemplate_Standard @1
GetEnrolTemplate_Short @2
GetEnrolTemplate_File @3
-------
PInvoke
namespace Components.SmartSensor
{
   internal class SmartSensorUnsafeNativeMethods
   {
      private SmartSensorUnsafeNativeMethods( )
{
		}
 
        [DllImport( "SmartSensors.Library.dll", EntryPoint="GetEnrolTemplate_Standard" )]
        internal static extern int GetEnrollmentTemplate
        (   
                byte[]          image, 
                uint            imageWidth, 
                uint            imageHeight,
                EnrollTemplate  enrollTemplate,
                Diagnostics     diagnostics,
                byte[]          normImage,
                uint            normWidth, 
                uint            normHeight,
                byte[]          localizedImage
        );

Open in new window

0
 

Author Comment

by:Rosman10
ID: 22989748
I guess I am a bit out of my depth here.

I have a C++ program that uses the .lib file. Would you be able to get me started with creating the DLL with say just one method used in the sample c++ program.

What would you need?
0
 
LVL 7

Expert Comment

by:psdavis
ID: 22990958
The attached snipet should actually have everything you need.  Which part in particular are you missing?
0
 

Author Comment

by:Rosman10
ID: 22991016
Apologies, Is it possible for me to provide some of the source code of my .LIB?

So you can point me in the right direction. If I could be shown how to do one method in the dll I think I would be ok from there.

What would you need?
0
 
LVL 7

Expert Comment

by:psdavis
ID: 22991492
Attach all of the source that you can.  I'll see what I can do.
0
 

Author Comment

by:Rosman10
ID: 22991694
Thanks, I can not attach a zip of the source code folders - the Attach file won't allow extensions eg config.h.

How can I send it to you.

Really appreciate your help.
0
 
LVL 7

Expert Comment

by:psdavis
ID: 22991729
You should be able to attach the .c and the .h files directly. Are you not able to?
0
 

Author Comment

by:Rosman10
ID: 22991755
I get the message
"The extension of the uploaded file is not in the list of accepted extensions."

Allowed: bmp doc gif jpeg jpg log mdb pdf png txt xls zip

But it also checks withing the zip - tried to upload with a bmp extensions but still catches it!

0
 
LVL 7

Expert Comment

by:psdavis
ID: 22991767
Convert your C code to .txt - that should work fine.
0
 

Author Comment

by:Rosman10
ID: 22991881
I hope you can work this - had to change everything to txt files

Good luck - and thanks again - get back to me if you need some description or more info
sdk-oti-otilib.zip
0
 
LVL 7

Expert Comment

by:psdavis
ID: 22994321
I didn't realize that you had full source to your .lib project.  All you need to do is compile this as a DLL instead of a LIB.
Change your solutions property...
Configuration Properties - General - Configuration Type to "Dynamic Library (.dll)".  It is probably set to "Static Library (.lib)" now.
Change all of the methods you want exposed by adding
__declspec(dllexport)
You also will want to add a '.DEF' file to your project.  Mine looks like this:
LIBRARY "SmartSensors.Library.dll"
; Explicit exports can go here
EXPORTS
GetEnrolTemplate_Standard @1
GetEnrolTemplate_Short @2
GetEnrolTemplate_File @3
GetEnrolTemplate_File_Short @4
GetEnrolTemplate_Norm @5
Then change your property
Configuration Properties - Linker - Input - Module Definition File
to the name of your .def file.
Once your .dll is created, then we can talk about calling it from C#
0
 

Author Comment

by:Rosman10
ID: 22999565
Thanks for your patience.

The code snippet below is for the method InitPort in SerialCom.c

Where do I put _declspec(dllexport) to expose the method InitPort in the dll?

I tried
 OTI_STATUS   _declspec(dllexport)   InitPort(void)
but i get the error
 'InitPort' : redefinition; different linkage      "

      




#include <windows.h>
#include "serial.h"
#include "frames.h"
#include "otilib.h"
#include "config.h"
/* Global descriptor for our serial port */
static HANDLE gComHandle = INVALID_HANDLE_VALUE;        // Closed
 
 
OTI_STATUS    InitPort(void)
{
    DCB	current_dcb;
	COMMTIMEOUTS com_timeout;
 
    /* Mapping between our own baudrate/stop bits structures and windows.
     *
     * This can be adapted to other serial libraries.
     */
    DWORD rates[] = {	0,
						50,
						75,
						CBR_110,
						134,
						150,
						200,
						CBR_300,
						CBR_600,
						CBR_1200,
						1800,
						CBR_2400,
						CBR_4800,
						CBR_9600,
						CBR_19200,
						CBR_38400,
						CBR_57600,
						CBR_115200,
						230400};
 
	/* Check our handle, close port if it's already in use */
    if(gComHandle != INVALID_HANDLE_VALUE)
    {
        CloseHandle(gComHandle);
        gComHandle = INVALID_HANDLE_VALUE;
    }
 
    if(!GetConfig())
        return OTI_CONFIG_ERROR;
 
    gComHandle = CreateFile((char *)gConf.port, 
		                    GENERIC_READ | GENERIC_WRITE, 
							0, 
							NULL, 
							OPEN_EXISTING, 
							FILE_ATTRIBUTE_NORMAL, 
							NULL);
 
    if (gComHandle == INVALID_HANDLE_VALUE)   // Couldn't open port
    {
        perror("OpenPort: Unable to open COM");
        return OTI_COM_ERROR;
    }
 
    /* Get current configuration of serial communication port. */
    if (GetCommState(gComHandle, &current_dcb) == 0) {
        return OTI_COM_ERROR;	// TODO(?): Map windows error to OTI status
    }
 
    /* Set our configured parameters */
    current_dcb.ByteSize = 8;
    current_dcb.StopBits = ((gConf.stop_bits == TWO_STOPBITS)?TWOSTOPBITS:ONESTOPBIT);
    current_dcb.Parity   = NOPARITY;
    current_dcb.BaudRate = rates[gConf.baud_rate];
 
	LOG_DEBUG("SerialComm: Set COM port parameters");
 
    /* Set current configuration of serial communication port. */
    if (SetCommState(gComHandle, &current_dcb) == 0) {
        return OTI_COM_ERROR;	// TODO(?): Map windows error to OTI status
    }
 
    /* set the time-out parameter into device control. */
 
	/* Specify time-out between charactor for receiving. */
    com_timeout.ReadIntervalTimeout = NEXT_BYTE_TIMEOUT * 100;	// Initial value in tenths of second
 
    /* Specify value that is multiplied by the requested 
	 * number of bytes to be read. 
	 */
    com_timeout.ReadTotalTimeoutMultiplier = 1;
 
    /* Specify value to be added to the product of the 
     * ReadTotalTimeoutMultiplier member.
	 */
    com_timeout.ReadTotalTimeoutConstant = FIRST_BYTE_TIMEOUT;
 
    /* Specify value that is multiplied by the requested 
	 * number of bytes to be sent. 
	 */
    com_timeout.WriteTotalTimeoutMultiplier = 0;
    
	/* Specify value to be added to the product of the 
     * WriteTotalTimeoutMultiplier member.
	 */
    com_timeout.WriteTotalTimeoutConstant = 0;
 
    SetCommTimeouts(gComHandle, &com_timeout);
 
	LOG_DEBUG("SerialComm: Set COM port timeouts");
    
    return OTI_OK;
}

Open in new window

0
 
LVL 7

Accepted Solution

by:
psdavis earned 1000 total points
ID: 23004406
It's all in how you set up the headers now.
In the project's properties, set Configuration Properties-C/C++-Preprocessor to
WIN32;_DEBUG;_WINDOWS;_USRDLL;MY_EXPORTS
This stuff is pretty well covered on the net if you have any problems with the 'dllexport' command.

My header file:
 
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
 
class MY_API CMySensors 
{
   public:
      CMySensors(void);
};
 
My C++ Code
 
CMySensors::CMySensors( )
{
    return;
}
 
MY_API int CompareTemplates_Standard(char *pTemplateA, char *pTemplateB,int *pResults)
{
    return MIR_CompareTemplates( pTemplateA, pTemplateB, pResults );
}

Open in new window

0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

830 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