【问题标题】:Include .dll from C#包含来自 C# 的 .dll
【发布时间】:2015-05-02 08:29:33
【问题描述】:

我有库说tenslib.h,我已使用Visual Studio 10 C 将其更改为tensLibs.dll(我使用过this)。

我想使用 C# 窗体应用程序打开它。我建立它并成功了。但是当我运行应用程序时,出现错误:

WindowsFormsCSharpApplication3.exe 中出现“System.DllNotFoundException”类型的未处理异常

附加信息:无法加载 DLL 'tensLibs.dll':找不到指定的模块。 (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.dllMSVCR100d.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;
}
 }

谁能告诉我这是什么问题,我该如何解决?

谢谢。

【问题讨论】:

  • 我已经显示了那个页面,但我仍然无法工作,我尝试使用控制台 C# 并且工作,窗口窗体应用程序和控制台 C# 有什么不同?
  • 当你说你把 tenslib.h 改成了 tenslib.dll,你的意思是你把它编译成一个 dll 对吧?
  • 而当你说你在文件夹中添加了tensLibs.dll,你的意思是你已经把它放在了bin/Release和bin/Debug吗?

标签: c# pinvoke dllimport


【解决方案1】:

互操作存在两个问题。

1.缺少依赖

System.DllNotFoundException 异常告诉您找不到您的 DLL 或其依赖项之一。将 DLL 放在与可执行文件相同的目录中。安装 DLL 的任何运行时依赖项,例如 MSVC 运行时。如果您的目标机器上没有用于 DLL 的 VS 版本,您可能需要编译 DLL 的发布版本。

2。调用约定不匹配

DLL 导出 cdecl 函数。您作为标准调用导入。 DllImport 属性需要指定正确的调用约定:

[DllImport("tensLibs.dll", CallingConvention = CallingConvention.Cdecl)]

旁白。 C中的布尔测试如下。零是假的,其他一切都是真的。不要在 C# 代码中测试 == 1。测试!= 0。但是,将bool 用于tens_init 的返回类型并让编组器为您完成工作会更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多