Reputation: 851
I have library say tenslib.h
, I have changed it to tensLibs.dll
using visual Studio 10 C (I have used this).
I want to open it using C# window form application. I build it and succeeded. But when I run the application, there is an error:
An unhandled exception of type 'System.DllNotFoundException' occurred in WindowsFormsCSharpApplication3.exe
Additional information: Unable to load DLL 'tensLibs.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Here the snapshot of my program
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices; //for export dll
namespace WindowsFormsCSharpApplication3
{
public partial class Form1 : Form
{
[DllImport("tensLibs.dll", EntryPoint = "tens_init")]
public static extern int tens_init([MarshalAsAttribute(UnmanagedType.LPStr)]string port);
private void button2_Click(object sender, EventArgs e)
{
if (tens_init("COM8") == 1)
label2.Text="Com 8 is initiated";
else
label2.Text="Com 8 does not exists";
}
}
}
I have add the tensLibs.dll in the folders but the error still appear. I have tried to add reference the dll file to the project but cannot added.
I used the depedency walker program to find the root of my .dll it need Kernel32.dll
and MSVCR100d.dll
and I have add to my folders, the error still occur.
I run in x86.
This is my Tens.h source
#ifndef TENSLIB_H_
#define TENSLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
int tens_init( char* port );
void tens_shutdown( void );
int tens_tutor( unsigned char finger );
void tens_shutdown( void );
int tens_settarget( unsigned char id );
int tens_enable( unsigned char supply_on, unsigned char bridge_on );
int tens_power( unsigned char power );
int tens_freq( unsigned char freq );
int tens_control( unsigned char power, unsigned char freq );
int tens_chargerate( unsigned char rate );
int tens_tunepower( unsigned char up );
int tens_writeconfig( void );
int tens_changeid( unsigned char id );
int tens_envs( unsigned char distance );
int tens_envsconf( unsigned char pmin, unsigned char pmax, unsigned char fmin, unsigned char fmax );
int tens_tutor( unsigned char finger );
int tens_garbage( void );
#ifdef __cplusplus
}
#endif
#endif
And for tens.c is to long I just put the tens_init()
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "tenslib.h"
#ifdef TENSLIB_CHATTER
#define PRINTF( ... ) printf( __VA_ARGS__ )
#else
#define PRINTF( ... )
#endif
#define TRUE 1
#define FALSE 0
#define PACKET_ENABLE 0
#define PACKET_POWER 1
#define PACKET_FREQ 2
#define PACKET_CONTROL 3
#define PACKET_CHARGERATE 4
#define PACKET_TUNEPOWER 5
#define PACKET_WRITECONFIG 6
#define PACKET_CHANGEID 7
#define PACKET_ENVS 8
#define PACKET_ENVSCONF 9
#define PACKET_TUTOR 10
static HANDLE hnd_serial = INVALID_HANDLE_VALUE;
static unsigned char patch_id = 0;
int tens_init( char* port )
{
DCB conf = { 0 };
conf.DCBlength = sizeof( conf );
if ( hnd_serial != INVALID_HANDLE_VALUE )
CloseHandle( hnd_serial );
PRINTF( "Opening serial connection.\n" );
hnd_serial = CreateFileA( port, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if ( hnd_serial == INVALID_HANDLE_VALUE ) {
PRINTF( "Failed to open serial port.\n" );
return FALSE;
}
if ( !GetCommState( hnd_serial, &conf ) ) {
PRINTF( "Failed to configure serial port.\n" );
CloseHandle( hnd_serial );
hnd_serial = INVALID_HANDLE_VALUE;
return FALSE;
}
conf.BaudRate = CBR_9600;
conf.ByteSize = 8;
conf.Parity = NOPARITY;
conf.StopBits = ONESTOPBIT;
if ( !SetCommState( hnd_serial, &conf ) ) {
PRINTF( "Failed to configure serial port.\n" );
CloseHandle( hnd_serial );
hnd_serial = INVALID_HANDLE_VALUE;
return FALSE;
}
PRINTF( "Connected to %s at 9600/8/N/1.\n", port );
return TRUE;
}
void tens_shutdown( void )
{
if ( hnd_serial != INVALID_HANDLE_VALUE ) {
PRINTF( "Closing serial connection.\n" );
CloseHandle( hnd_serial );
hnd_serial = INVALID_HANDLE_VALUE;
}
}
can any one tell me what is this problem, and how can i fix it?
Thank you.
Upvotes: 0
Views: 305
Reputation: 613451
There are two problems with the interop.
1. Missing Dependency
The System.DllNotFoundException
exception tells you that your DLL, or one of its dependencies cannot be found. Place the DLL in the same directory as the executable. Install any runtime dependencies of the DLL, for instance the MSVC runtime. You may need to compile the release build of the DLL if you don't have the version of VS used for the DLL on your target machine.
2. Calling convention mismatch
The DLL exports cdecl functions. You import as stdcall. The DllImport
attribute needs to specify the correct calling convention:
[DllImport("tensLibs.dll", CallingConvention = CallingConvention.Cdecl)]
An aside. Boolean testing in C is as follows. Zero is false, everything else is true. Don't test == 1
in your C# code. Test != 0
. However, it is simpler to use bool
for the return type of tens_init
and let the marshaler do the work for you.
Upvotes: 2