从 C# 中包含 .dll
Include .dll from C#
我有库说 tenslib.h
,我已经使用 visual Studio 10 C 将其更改为 tensLibs.dll
(我使用了 this)。
我想使用 C# window 表单应用程序打开它。我构建它并成功了。但是当我运行申请的时候,出现了错误:
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)
这是我程序的快照
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";
}
}
}
我已经在文件夹中添加了tensLibs.dll,但错误仍然出现。我已经尝试将 dll 文件的引用添加到项目中,但无法添加。
我使用 depedency walker 程序找到了我的 .dll 的根目录,它需要 Kernel32.dll
和 MSVCR100d.dll
并且我已经添加到我的文件夹,错误仍然存在。
我在 x86 中 运行。
这是我的Tens.h来源
#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
因为 tens.c 太长了,我只是把 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;
}
}
谁能告诉我这是什么问题,我该如何解决?
谢谢。
互操作有两个问题。
1.缺少依赖关系
System.DllNotFoundException
异常告诉您找不到您的 DLL 或其依赖项之一。将 DLL 放在与可执行文件相同的目录中。安装 DLL 的任何运行时依赖项,例如 MSVC 运行时。如果目标计算机上没有用于 DLL 的 VS 版本,则可能需要编译 DLL 的发布版本。
2。调用约定不匹配
DLL 导出 cdecl 函数。您导入为 stdcall。 DllImport
属性需要指定正确的调用约定:
[DllImport("tensLibs.dll", CallingConvention = CallingConvention.Cdecl)]
题外话。 C中的布尔测试如下。零是假的,其他都是真的。不要在 C# 代码中测试 == 1
。测试!= 0
。但是,对于 tens_init
的 return 类型使用 bool
并让封送拆收器为您完成工作会更简单。
我有库说 tenslib.h
,我已经使用 visual Studio 10 C 将其更改为 tensLibs.dll
(我使用了 this)。
我想使用 C# window 表单应用程序打开它。我构建它并成功了。但是当我运行申请的时候,出现了错误:
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)
这是我程序的快照
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";
}
}
}
我已经在文件夹中添加了tensLibs.dll,但错误仍然出现。我已经尝试将 dll 文件的引用添加到项目中,但无法添加。
我使用 depedency walker 程序找到了我的 .dll 的根目录,它需要 Kernel32.dll
和 MSVCR100d.dll
并且我已经添加到我的文件夹,错误仍然存在。
我在 x86 中 运行。
这是我的Tens.h来源
#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
因为 tens.c 太长了,我只是把 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;
}
}
谁能告诉我这是什么问题,我该如何解决?
谢谢。
互操作有两个问题。
1.缺少依赖关系
System.DllNotFoundException
异常告诉您找不到您的 DLL 或其依赖项之一。将 DLL 放在与可执行文件相同的目录中。安装 DLL 的任何运行时依赖项,例如 MSVC 运行时。如果目标计算机上没有用于 DLL 的 VS 版本,则可能需要编译 DLL 的发布版本。
2。调用约定不匹配
DLL 导出 cdecl 函数。您导入为 stdcall。 DllImport
属性需要指定正确的调用约定:
[DllImport("tensLibs.dll", CallingConvention = CallingConvention.Cdecl)]
题外话。 C中的布尔测试如下。零是假的,其他都是真的。不要在 C# 代码中测试 == 1
。测试!= 0
。但是,对于 tens_init
的 return 类型使用 bool
并让封送拆收器为您完成工作会更简单。