[英]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.