簡體   English   中英

導入 .NET Core 3.0 加載的 DLL 失敗

[英]Failed to import DLL loaded by .NET Core 3.0

我有一個 .NET Core 3 項目,它使用一個使用 Mosquitto 與 MQTT Broker 對話的包裝庫。

包裝器定義為:

public static class MosquittoWrapper
  {
    public const string MosquittoDll = "mosq";

    [StructLayout(LayoutKind.Sequential)]
    public struct mosquitto_message
    {
      public int mid;
      public string topic;
      public byte[] payload;
      public int payloadlen;
      public int qos;
      [MarshalAs(UnmanagedType.U1)]
      public bool retain;
    }

    public delegate void ConnectCallbackDelegate(int result);
    public delegate void MessageCallbackDelegate(mosquitto_message mesage);

    [DllImport(MosquittoDll, CallingConvention = CallingConvention.Cdecl)]
    public static extern int mosq_init();

    [DllImport(MosquittoDll, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int mosq_set_tls_psk(string psk, string identity, string? ciphers);

    [DllImport(MosquittoDll, CallingConvention = CallingConvention.Cdecl)]
    internal static extern void mosq_set_callback(ConnectCallbackDelegate? connect_callback, MessageCallbackDelegate? message_callback);

    [DllImport(MosquittoDll, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int mosq_connect(string host, int port, int keepalive);

    [DllImport(MosquittoDll, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int mosq_subscribe_topic(string topic);

    [DllImport(MosquittoDll, CallingConvention = CallingConvention.Cdecl)]
    internal static extern void mosq_runloop(int timeout, int max_packets, int sleep_on_reconnect);

    [DllImport(MosquittoDll, CallingConvention = CallingConvention.Cdecl)]
    internal static extern int mosq_destroy();
  }

header 定義為:

#pragma once

#ifndef MOSQUITTO_H_
#define MOSQUITTO_H_

#include <mosquitto.h>

#ifdef _WIN32
#    ifdef LIBRARY_EXPORTS
#        define LIBRARY_API __declspec(dllexport)
#    else
#        define LIBRARY_API __declspec(dllimport)
#    endif
#elif
#    define LIBRARY_API
#endif


typedef void (*CONNECT_CALLBACK)(int);
typedef void (*MESSAGE_CALLBACK)(const struct mosquitto_message*);

// return value 0 represents success. Or ENOMEM, EINVAL when error.
LIBRARY_API int mosq_init();
LIBRARY_API int mosq_set_tls_psk(char* psk, char* identity, char* ciphers);
LIBRARY_API void mosq_set_callback(CONNECT_CALLBACK connect_callback, MESSAGE_CALLBACK message_callback);
LIBRARY_API int mosq_connect(char* host, int port, int keepalive);
LIBRARY_API int mosq_subscribe_topic(char* topic);
LIBRARY_API void mosq_runloop(int timeout, int max_packets, int sleep_on_reconnect);
LIBRARY_API int mosq_destroy();

#endif // MOSQUITTO_H_

問題是當我嘗試啟動項目時,.NET Core 拋出異常。 System.DllNotFoundException: 'Unable to load DLL 'mosq' or one of its dependencies: The specified module could not be found. (0x8007007E)'

這根本沒有意義。 dll 及其依賴項被復制到加載 mosq dll 的文件夾中。 此外,正在運行的進程顯式地寫入有關相關 dll 加載的符號。 我還嘗試將 dll 折騰到不同的文件夾中,但這沒有用。 go 會出現什么問題?

dotnet 核心中的 DLL 導入的工作方式與 .net 框架中的相同

Go 到https://mosquitto.org/並下載(源代碼/dll)。 在這里,我抓取 windows 二進制文件“mosquitto.dll”。

Generate a C# program with a wrapper for the above dll (API: https://mosquitto.org/api/files/mosquitto-h.html ).

這里我將只使用 init function 作為概念證明

using System;
using System.Runtime.InteropServices;

namespace aac
{
    class Program
    {
        static void Main(string[] args)
        {
            // Just test the init function
            MosquittoWrapper.mosquitto_lib_init();
            Console.WriteLine("success");
        }
    }

    public static class MosquittoWrapper
    {
        // Same name as DLL
        public const string MosquittoDll = "mosquitto";

        // https://mosquitto.org/api/files/mosquitto-h.html#mosquitto_lib_init
        [DllImport(MosquittoDll, CallingConvention = CallingConvention.Cdecl)]
        public static extern int mosquitto_lib_init();
    }
}

然后構建項目

PS C:\Users\bburns\code\scratch\aac\aac> dotnet build
Microsoft (R) Build Engine version 16.3.0+0f4c62fea for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 20.94 ms for C:\Users\bburns\code\scratch\aac\aac\aac.csproj.
  aac -> C:\Users\bburns\code\scratch\aac\aac\bin\Debug\netcoreapp3.0\aac.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.61

然后將 mosquitto.dll 放在與執行程序集相同的文件夾中

 bin\Debug\netcoreapp3.0

運行程序:

PS C:\Users\bburns\code\scratch\aac\aac> dotnet run
success 

請注意,如果名稱不匹配或找不到 dll ,您將生成DllFileNotFoundException

public const string MosquittoDll = "mosquittoz";

構建並運行

PS C:\Users\bburns\code\scratch\aac\aac> dotnet run
Unhandled exception. System.DllNotFoundException: Unable to load DLL 'mosquittoz' or one of its dependencies: The specified module could not be found. (0x8007007E)
   at aac.MosquittoWrapper.mosquitto_lib_init()
   at aac.Program.Main(String[] args) in C:\Users\bburns\code\scratch\aac\aac\Program.cs:line 10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM