【发布时间】:2019-11-27 22:36:57
【问题描述】:
我目前正在使用 C# 创建一个 Windows 窗体应用程序,其中需要在运行时通过文件对话框在应用程序中调用用 C 编写的具有自己的结构和函数的不同 .dll 文件以获取它们的路径。据我了解,这意味着我不能使用[DllImport("filename")],因为路径值不是在编译时确定的。我至少得到了 .h 文件,并且还保证导出的函数将具有相同的名称。
我在网上浏览了很多不同的帖子,大多数解决方案最终都指向了 PInvoke、Reflection 和/或 InteropServices,但没有明确的示例说明该怎么做。
由于每个这样的 dll 都定义了自己的结构,我希望能够: 1.使用dll本身的struct定义,避免在C#中重新定义一切, 2. 加载dll后,在应用程序的不同点使用函数。
诚然,我是 C# 的新手,所以我在上面尝试做的事情可能甚至不可能。但我现在不知所措,因为我什至找不到从哪里开始学习以解决这个问题。任何帮助将不胜感激。
以下是参考代码:
其中一个dll的头文件classifier.h:
#ifndef SRC_CLASSIFIER_H_
#define SRC_CLASSIFIER_H_
#include "vector.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILD_DYNAMIC_LIB
#ifdef _WIN32
#define _EXPORT __declspec(dllexport)
#else
#define _EXPORT __attribute__((visibility("default")))
#endif
#else
#define _EXPORT
#endif
/** Error codes */
#define CLASSIFIER_OK 0x00
#define CLASSIFIER_INIT_MISSING 0x01
#define CLASIFIER_NO_SAMPLES_PROVIDED 0x02
#define CLASSIFIER_PARAM_OUT_OF_RANGE 0x03
#define CLASSIFIER_DECISION_BUFFER_LEN 20
#define CLASSIFIER_MAX_BURST_LEN 32
typedef struct {
uint8_t sensitivity;
uint8_t noTruckRecognitionLimit;
uint8_t noTruckRecognitionHyst;
uint16_t intensityLimit[CLASSIFIER_MAX_BURST_LEN];
} classifier_Parameter_t;
typedef enum { UNDEFINED = 0x00, TRUCK = 0x01, NO_TRUCK = 0x02 } class_t;
typedef struct {
class_t classifiedAs;
} classifier_Result_t;
typedef struct {
uint8_t noOfSamples;
vec3d_t accSamples[CLASSIFIER_MAX_BURST_LEN];
} classifier_Input_t;
_EXPORT uint8_t classifier_api_Init(classifier_Parameter_t *para);
_EXPORT uint8_t classifier_api_Execute(classifier_Input_t *input,
classifier_Result_t *result);
_EXPORT uint8_t classifier_api_Reset(void);
#ifdef __cplusplus
}
#endif
#endif /* SRC_CLASSIFIER_H_ */
还有 C# 文件 MainForm.cs:
using System;
...
namespace ClassifierEval
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnLoadDll_Click(object sender, EventArgs e)
{
openFileDialogLoadDll.ShowDialog();
}
private void openFileDialogLoadDll_FileOk(object sender, CancelEventArgs e)
{
lblLoadedDll.Text = openFileDialogLoadDll.FileName;
///Loading the DLL here?
}
...
}
【问题讨论】:
-
使用来自原生 dll 的 dll 中的结构定义?那里没有结构定义...
-
我的意思是 .h 文件中显示的结构,例如 classifier_Parameter_t
-
then 1. 将原生结构转换为 C# 2. 将原生函数转换为委托 3. 使用来自 winapi 的
LoadLibrary,GetProcAddress,FreeLibrary4. 使用Marshal.GetDelegateForFunctionPointer<>从函数中获取委托指针
标签: c# c winforms-interop