草庐IT

c# - DLL 不能在 C# 中运行

coder 2024-02-25 原文

每当我尝试通过 Visual Studio 在 C# 中引用我自己的 DLL 时,它都会告诉我它无法引用 DLL,因为它不是 COM 库。

我在互联网上进行了搜索以找到解决此问题的方法,但没有明确的答案,也没有真正提供任何帮助。这是一个相当“简单”的 DLL,它从指纹扫描仪捕获原始图片数据。我已经测试过 C++ 代码在我尝试将它变成 DLL 之前工作得很好,你知道的。

我遵循了 Microsoft 关于如何制作 DLL 的指南,这是我最终得到的:

  • JTBioCaptureFuncsDll.h
  • JTBioCaptureFuncsDll.cpp
  • JTBioCapture.cpp

JTBioCaptureFuncsDll.h

#ifdef JTBIOCAPTUREFUNCSDLL_EXPORTS
#define JTBIOCAPTUREFUNCSDLL_API __declspec(dllexport)
#else
#define JTBIOCAPTUREFUNCSDLL_API __declspec(dllimport)
#endif

using byte = unsigned char*;

struct BioCaptureSample {
    INT32 Width;
    INT32 Height;
    INT32 PixelDepth;
    byte Buffer;
};

JTBioCaptureFuncsDll.cpp

// JTBioCapture.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

namespace JTBioCapture
{
    using byte = unsigned char*;

    class JTBioCapture
    {
    public:
        // Returns a Struct with Information Regarding the Fingerprint Sample
        static JTBIOCAPTUREFUNCSDLL_API BioCaptureSample CaptureSample();
    };
}

JTBioCapture.cpp

/*
* Courtesy of WinBio God Satish Agrawal on Stackoverflow
*/
BioCaptureSample CaptureSample()
{
    HRESULT hr = S_OK;
    WINBIO_SESSION_HANDLE sessionHandle = NULL;
    WINBIO_UNIT_ID unitId = 0;
    WINBIO_REJECT_DETAIL rejectDetail = 0;
    PWINBIO_BIR sample = NULL;
    SIZE_T sampleSize = 0;

    // Connect to the system pool. 
    hr = WinBioOpenSession(
        WINBIO_TYPE_FINGERPRINT,    // Service provider
        WINBIO_POOL_SYSTEM,         // Pool type
        WINBIO_FLAG_RAW,            // Access: Capture raw data
        NULL,                       // Array of biometric unit IDs
        0,                          // Count of biometric unit IDs
        WINBIO_DB_DEFAULT,          // Default database
        &sessionHandle              // [out] Session handle
        );
    if (FAILED(hr))
    {
        wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr);
        goto e_Exit;
    }

    // Capture a biometric sample.
    wprintf_s(L"\n Calling WinBioCaptureSample - Swipe sensor...\n");
    hr = WinBioCaptureSample(
        sessionHandle,
        WINBIO_NO_PURPOSE_AVAILABLE,
        WINBIO_DATA_FLAG_RAW,
        &unitId,
        &sample,
        &sampleSize,
        &rejectDetail
        );
    if (FAILED(hr))
    {
        if (hr == WINBIO_E_BAD_CAPTURE)
        {
            wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail);
        }
        else
        {
            wprintf_s(L"\n WinBioCaptureSample failed. hr = 0x%x\n", hr);
        }
        goto e_Exit;
    }

    wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId);
    wprintf_s(L"\n Captured %d bytes.\n", sampleSize);

    // Courtesy of Art "Messiah" Baker at Microsoft
    PWINBIO_BIR_HEADER BirHeader = (PWINBIO_BIR_HEADER)(((PBYTE)sample) + sample->HeaderBlock.Offset);
    PWINBIO_BDB_ANSI_381_HEADER AnsiBdbHeader = (PWINBIO_BDB_ANSI_381_HEADER)(((PBYTE)sample) + sample->StandardDataBlock.Offset);
    PWINBIO_BDB_ANSI_381_RECORD AnsiBdbRecord = (PWINBIO_BDB_ANSI_381_RECORD)(((PBYTE)AnsiBdbHeader) + sizeof(WINBIO_BDB_ANSI_381_HEADER));
    PBYTE firstPixel = (PBYTE)((PBYTE)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD);
    int width = AnsiBdbRecord->HorizontalLineLength;
    int height = AnsiBdbRecord->VerticalLineLength;

    wprintf_s(L"\n ID: %d\n", AnsiBdbHeader->ProductId.Owner);
    wprintf_s(L"\n Width: %d\n", AnsiBdbRecord->HorizontalLineLength);
    wprintf_s(L"\n Height: %d\n", AnsiBdbRecord->VerticalLineLength);

    BioCaptureSample returnSample;

    byte byteBuffer;
    for (int i = 0; i < AnsiBdbRecord->BlockLength; i++) {
        byteBuffer[i] = firstPixel[i];
    }
    returnSample.Buffer = byteBuffer;
    returnSample.Height = height;
    returnSample.Width = width;
    returnSample.PixelDepth = AnsiBdbHeader->PixelDepth;

    /*
    * NOTE: (width / 3) is necessary because we ask for a 24-bit BMP but is only provided
    * a greyscale image which is 8-bit. So we have to cut the bytes by a factor of 3.
    */
    // Commented out as we only need the Byte buffer. Comment it back in should you need to save a BMP of the fingerprint.
    // bool b = SaveBMP(firstPixel, (width / 3), height, AnsiBdbRecord->BlockLength, L"C:\\Users\\smf\\Desktop\\fingerprint.bmp");
    // wprintf_s(L"\n Success: %d\n", b);

e_Exit:
    if (sample != NULL)
    {
        WinBioFree(sample);
        sample = NULL;
    }

    if (sessionHandle != NULL)
    {
        WinBioCloseSession(sessionHandle);
        sessionHandle = NULL;
    }

    wprintf_s(L"\n Press any key to exit...");
    _getch();

    return returnSample;
}

想法是在 C# 中调用“CaptureSample()”,然后代码 try catch 指纹扫描。当它进行扫描时,应该将一个结构返回给它可以使用的 C#,其中包含:

  • 字节缓冲区
  • 图片高度
  • 图片宽度
  • 图像像素深度

但是当我尝试在我的 C# 项目中引用 DLL 时,出现以下错误:

我也尝试过使用TlbImp.exe 工具制作动态链接库,但无济于事。它告诉我 DLL 不是有效的类型库。

所以我在这里有点迷路了。我是 C++ 的新手,所以制作 Interop/COM 组件不是我以前做过的事情,也不是制作用于 C# 的 DLL。

最佳答案

您不能在 .NET 项目中引用用 C++ 编写的非托管代码库。 因此,要从此类库中调用代码,您必须使用 DllImport ,或使用 WrapperClass .

我引用了这个答案:https://stackoverflow.com/a/574810/4546874 .

关于c# - DLL 不能在 C# 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34020703/

有关c# - DLL 不能在 C# 中运行的更多相关文章

  1. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  2. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  5. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  6. ruby-on-rails - Ruby rand() 不能接受变量? - 2

    我对此有点困惑。我在RoR项目中的最终目标是从我的数据库中获取单个随机配置文件。我想它应该是这样的:@profile=Profile.find_by_user_id(rand(User.count))它一直抛出错误,因为user_id0不存在,所以我把它的一部分拿出来检查发生了什么:@r=rand(User.count)每次都返回0。发生什么了?我注册了5个假用户和5个相关配置文件来测试这个。如果我将Profile.find_by_user_id(rand(User.count))重写为Profile.find_by_user_id(3)它工作得很好。User.count也在工作。所以

  7. ruby - 在 rake 任务中运行 capybara - 2

    如何在Rake任务中运行Capybara功能?例如:访问('http://google.com')谢谢! 最佳答案 在任务中尝试这样的事情:require'capybara'require'capybara/dsl'Capybara.current_driver=:seleniumBrowser=Class.new{includeCapybara::DSL}page=Browser.new.pagepage.visit("http://www.google.com")puts(page.html)

  8. ruby - 为什么我不能从 ruby​​ 中的选定键创建新的散列? - 2

    这个问题困扰了我一段时间。这不是一件困难的事情,但我不知道为什么没有简单的方法来做到这一点,我敢打赌有但我没有看到。我只想取一个散列,像这样:cars={:bob=>'Pontiac',:fred=>'Chrysler',:lisa=>'Cadillac',:mary=>'Jaguar'}然后做类似的事情cars[:bob,:lisa]得到{:bob=>'Pontiac',:lisa=>'Cadillac'}我这样做了,效果很好:classHashdefpick(*keys)Hash[select{|k,v|keys.include?(k)}]endendruby-1.8.7-p249

  9. ruby-on-rails - 如何在 gem 中运行 Rails 应用程序? - 2

    我不确定这种事情是否很常见,但我一直在尝试创建只是Rails应用程序包装器的gem。我的gem将有一个生成器来创建config.ru,但Rails应用程序将位于gem的lib目录中。我需要知道如何“嵌入”Rails应用程序并对其进行配置,以便它可以在gem中运行。例如:$mygemnewprojectmygemcreatedadirectorycalled"project"withthefollowingfiles:project/config.ruproject/widgets/project/foobars/我的gem还将生成一些需要以某种方式添加到Rails的目录,以便我可以从G

  10. ruby-on-rails - 为什么 Rails 可以使用 `if` 作为哈希键但在 Ruby 中不能 - 2

    在纯Rubyirb中,不能输入{if:1}。该语句不会终止,因为irb认为if不是符号,而是if语句的开始。那么为什么Rails可以有before_filter接受if作为参数?该指南的代码如下:classOrderunless也会发生同样的事情。 最佳答案 这是一个irb问题,而不是Ruby。bash=>ruby-e"puts({if:1})"bash=#{:if=>1}您可以改用pry。它将正确读取输入。https://github.com/pry/pry 关于ruby-on-rai

随机推荐