... Новичок здесь: D
Я пытаюсь изучить механизм плагинов
У меня есть exe и dll и в Winform, и в основном приложении есть текстовое поле с двумя функцияминапример, который устанавливает и получает текст текстового поля, и эти две функции являются API.
public void SetDataX(string data)
{
textboxx.Text = data;
}
public string GetDataX()
{
return textboxx.Text;
}
Хорошо, тогда я создал класс для хранения функций и добавил его в dll и exe:
plugin_interface.cs
namespace Plugin_Mech_Study
{
public class app_api
{
public Action<string> SetData { get; set; }
public Func<string> GetData { get; set; }
}
}
В DLL я сделал функцию, которая принимает app_api
, и я называю ее Load(app_api apibridge)
Теперь, когда япытаюсь отражение, чтобы вызвать и передать app_api в dll, я получаю эту ошибку:
System.ArgumentException: 'Объект типа' Plugin_Mech_Study.app_api 'не может быть преобразованнабрать 'pluginTest.app_api'. '
Вот как я вызываю dll:
private void load_plugin(string pluginadd)
{
var loadplugin = Assembly.LoadFile(pluginadd);
Type t = loadplugin.GetType("pluginTest.plugin");
app_api newapi = new app_api();
newapi.SetData = SetDataX;
newapi.GetData = GetDataX;
var apimethod = t.GetMethod("Load");
if (apimethod == null)
{
MessageBox.Show("Can't Generate API!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(501);
}
var o2 = Activator.CreateInstance(t);
var result2 = apimethod.Invoke(o2, new object[] { newapi }); /// Error Happens Here
}
Как мне решить эту проблему? Если вопрос недостаточно ясен, я могу загрузить исходные коды. Спасибо
Редактировать 2:
Вот Минimal коды
Plugin_Mech_Study [Winform exe] => Program.cs
using System;
using System.Windows.Forms;
namespace Plugin_Mech_Study
{
static class Program
{
[STAThread]
static void Main()
{
Application.Run(new mainapp());
}
}
}
Plugin_Mech_Study [Winform exe] => mainapp.cs
using System;
using System.Windows.Forms;
using System.Reflection;
namespace Plugin_Mech_Study
{
public partial class mainapp : Form
{
public mainapp()
{
InitializeComponent();
}
public void SetDataX(string data)
{
textboxx.Text = data;
}
public string GetDataX()
{
return textboxx.Text;
}
private void load_plugin(string pluginadd)
{
var loadplugin = Assembly.LoadFile(pluginadd);
Type t = loadplugin.GetType("pluginTest.plugin");
var guimethod = t.GetMethod("GetControl");
if (guimethod == null)
{
MessageBox.Show("Can't Load GUI!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
var o = Activator.CreateInstance(t);
var result = guimethod.Invoke(o, null);
plug_ui.Controls.Add((UserControl)result);
app_api newapi = new app_api();
newapi.SetData = SetDataX;
newapi.GetData = GetDataX;
var apimethod = t.GetMethod("Load");
if (apimethod == null)
{
MessageBox.Show("Can't Generate API!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
var o2 = Activator.CreateInstance(t);
var result2 = apimethod.Invoke(o2, new object[] { newapi });
}
private void button1_Click(object sender, EventArgs e)
{
load_plugin(Environment.CurrentDirectory + @"\tzplugins\pluginTest.dll");
}
}
}
Plugin_Mech_Study [Winform exe] => mainapp.Designer.cs
namespace Plugin_Mech_Study
{
partial class mainapp
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textboxx = new System.Windows.Forms.TextBox();
this.plug_ui = new System.Windows.Forms.Panel();
this.SuspendLayout();
this.button1.BackColor = System.Drawing.Color.SteelBlue;
this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.button1.ForeColor = System.Drawing.Color.AntiqueWhite;
this.button1.Location = new System.Drawing.Point(253, 24);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(147, 52);
this.button1.TabIndex = 0;
this.button1.Text = "Load Plugin";
this.button1.UseVisualStyleBackColor = false;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.textboxx.BackColor = System.Drawing.SystemColors.Info;
this.textboxx.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textboxx.Location = new System.Drawing.Point(12, 24);
this.textboxx.Multiline = true;
this.textboxx.Name = "textboxx";
this.textboxx.Size = new System.Drawing.Size(235, 170);
this.textboxx.TabIndex = 2;
this.textboxx.Text = "This is a Test";
this.plug_ui.BackColor = System.Drawing.SystemColors.Info;
this.plug_ui.Location = new System.Drawing.Point(253, 82);
this.plug_ui.Name = "plug_ui";
this.plug_ui.Size = new System.Drawing.Size(147, 112);
this.plug_ui.TabIndex = 3;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.RoyalBlue;
this.ClientSize = new System.Drawing.Size(417, 210);
this.Controls.Add(this.plug_ui);
this.Controls.Add(this.textboxx);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "mainapp";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Plugin Loader";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textboxx;
private System.Windows.Forms.Panel plug_ui;
}
}
Plugin_Mech_Study [Winform exe] => plugin_interface.cs
using System;
namespace Plugin_Mech_Study
{
public interface api_interface
{
Action<string> SetData { get; set; }
Func<string> GetData { get; set; }
}
public class app_api : api_interface
{
public Action<string> SetData { get; set; }
public Func<string> GetData { get; set; }
}
}
pluginTest [Библиотека классов] => plugin.cs
using System.Windows.Forms;
namespace pluginTest
{
public class plugin : plugin_interface
{
private plugin_UI pluginUI;
public UserControl GetControl() {
var new_gui = new plugin_UI();
pluginUI = new_gui;
return new_gui;
}
public void Load(api_interface apibridge) {
pluginUI.LoadPlugin(apibridge);
}
}
}
pluginTest [Библиотека классов] => plugin_interface.cs
using System;
using System.Windows.Forms;
namespace pluginTest
{
public interface plugin_interface
{
UserControl GetControl();
void Load(api_interface apibridge);
}
public interface api_interface
{
Action<string> SetData { get; set; }
Func<string> GetData { get; set; }
}
public class app_api : api_interface
{
public Action<string> SetData { get; set; }
public Func<string> GetData { get; set; }
}
}
pluginTest [Библиотека классов] => plugin_UI.cs
using System;
using System.Windows.Forms;
namespace pluginTest
{
public partial class plugin_UI : UserControl
{
api_interface bridgedAPI;
public void LoadPlugin(api_interface apibridge)
{
bridgedAPI = apibridge;
}
public plugin_UI()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = bridgedAPI.GetData();
}
private void button2_Click(object sender, EventArgs e)
{
bridgedAPI.SetData(textBox1.Text);
}
}
}
pluginTest [Библиотека классов] => plugin_UI.Designer.cs
namespace pluginTest
{
partial class plugin_UI
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
this.button1.BackColor = System.Drawing.SystemColors.HotTrack;
this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.button1.ForeColor = System.Drawing.SystemColors.Control;
this.button1.Location = new System.Drawing.Point(15, 14);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(118, 25);
this.button1.TabIndex = 0;
this.button1.Text = "Get Data";
this.button1.UseVisualStyleBackColor = false;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button2.BackColor = System.Drawing.SystemColors.HotTrack;
this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.button2.ForeColor = System.Drawing.SystemColors.Control;
this.button2.Location = new System.Drawing.Point(15, 47);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(118, 25);
this.button2.TabIndex = 1;
this.button2.Text = "Set Data";
this.button2.UseVisualStyleBackColor = false;
this.button2.Click += new System.EventHandler(this.button2_Click);
this.textBox1.BackColor = System.Drawing.SystemColors.Info;
this.textBox1.ForeColor = System.Drawing.Color.Red;
this.textBox1.Location = new System.Drawing.Point(15, 79);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(118, 20);
this.textBox1.TabIndex = 2;
this.textBox1.Text = "Test Data";
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Info;
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "plugin_UI";
this.Size = new System.Drawing.Size(147, 112);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.TextBox textBox1;
}
}
И вот исходный код .