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

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?
Rosman10Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

psdavisCommented:
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
Rosman10Author Commented:
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
psdavisCommented:
Let me get to work in about 4 hours and I'll post code I used.
0
Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

psdavisCommented:
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
Rosman10Author Commented:
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
psdavisCommented:
The attached snipet should actually have everything you need.  Which part in particular are you missing?
0
Rosman10Author Commented:
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
psdavisCommented:
Attach all of the source that you can.  I'll see what I can do.
0
Rosman10Author Commented:
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
psdavisCommented:
You should be able to attach the .c and the .h files directly. Are you not able to?
0
Rosman10Author Commented:
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
psdavisCommented:
Convert your C code to .txt - that should work fine.
0
Rosman10Author Commented:
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
psdavisCommented:
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
Rosman10Author Commented:
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
psdavisCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.