从 C# 程序访问 DLL 中的方法
Posted
技术标签:
【中文标题】从 C# 程序访问 DLL 中的方法【英文标题】:Access a method from a DLL from C# program 【发布时间】:2011-06-17 22:16:36 【问题描述】:我有一个 C 程序并创建了一个 DLL 文件。我正在使用 Windows Vista 和 Visual C++。
现在我需要从 C# 代码的 Main() 方法访问该 DLL 中的方法。这样做的步骤是什么?
到目前为止,我已经添加了 DLL 文件作为参考,之后我该怎么办?
这只是一个例子:
int main1( void )
prinf("Hello World");
请注意,这个类也使我们能够使用其他 .lib 函数,但我能够成功地从中创建一个 DLL。 (我不知道这是否相关)
现在我需要从我的 C# Main() 访问这个方法;
[STAThread]
static void Main()
// I need to call that main1() method here
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
【问题讨论】:
无法添加对本机 C DLL 的引用。显然,您没有使用真正的 C dll,也许是 C++/CLI 的。在这种情况下不需要什么特别的,您公开的“ref class”声明可以直接在 C# 程序中使用。 是的,它是一个 C++/CLI 项目。根据您的回答,它似乎可以直接完成,通过说'ref class'是指我的 C 类吗?以及如何公开?到目前为止我所做的步骤是,添加 dll 作为参考,并添加以下语句using detect.h
,并尝试从 C#、Main() 方法访问它,例如; detect.the_method_i_need()
,但它没有那样工作。帮助
【参考方案1】:
请参阅using a class defined in a c++ dll in c# code,它有一个很好的接受答案。正如 Hans Passant 在 cmets 中所写,您不能将本机 DLL 添加为对 C# 项目的引用。
当我引用自己的一个本地 DLL 时,我通常要么在 C# 项目和生成本地 DLL 的项目之间添加依赖关系,要么将 DLL 作为链接内容文件添加到 C# 项目中,就像这样:
-
右键单击项目并选择“添加”>“现有项目”。
浏览并选择所需的 DLL,但不要单击添加。
点击添加按钮右侧的小箭头并选择添加为链接。
选择现在出现在 C# 项目中的 DLL 并转到其属性。
确保您已将 Build Action 设置为 Content。
这会将 DLL 复制到 C# 项目的 bin\Debug
文件夹,并确保如果您决定创建安装项目,您可以轻松引用所有内容文件并包含它们在 Microsoft 安装程序包中。
现在,为了能够查看在您的本地 DLL 中编写的函数,您必须注意导出它们(参见 Exporting C Functions for Use in C or C++ Language Executables 和 Exporting from a DLL Using __declspec(dllexport))。所以你必须在你的函数声明周围添加一个extern "C"
块(我假设你在 .cpp 源文件中编写了你的代码,这意味着编译器将发出 mangled 函数名称,如果你没有将它们声明为 extern "C"
):
extern "C"
__declspec (dllexport) void __cdecl Foo(const char* arg1);
...
void Foo(const char* arg1)
printf ("Hello %s !", arg1);
__declspec (dllexport)
装饰意味着编译器/链接器必须使函数从 DLL 外部可见。 __cdecl
定义了如何将参数传递给函数(执行此操作的标准“C”方式)。
在您的 C# 代码中,您必须引用 DLL 的导出方法:
class Program
[DllImport("mydll.dll")]
internal static extern void Foo(string arg1);
static void Main()
Program.Foo ("Pierre");
您应该阅读Platform Invoke Tutorial,它提供了所有血淋淋的细节。
【讨论】:
您好@Pierre,我按照您的步骤操作,但是当我编译时,我不确定如何将 Content 设置为 Build Action代码,我没有在我的 C# 项目的 bin\Debug 中找到我的 DLL 的副本。希望你能在这里帮助我,你能告诉我如何访问我从我的 C# 项目的 Main() 方法中添加的那个 DLL 的方法。 @illep:点击C#项目中的DLL文件,按F4。在“属性”工具窗口中,第一行标记为“构建操作”。单击它的右侧,选择“内容”。确保将“复制到输出目录”设置为复制选项之一。 @illep:编辑您的帖子并添加您想要访问的 C 代码示例。您必须确保使用 DLL 导出指令正确修饰您的 C 函数。 我用示例代码编辑了我的帖子,请帮助我。干杯!【参考方案2】:您正在寻找Platform Invoke 和[DllImport]
属性。
【讨论】:
我做了以下 /n ` [DllImport("detect.dll")] internal static extern int main1();` ,detect.dll
是我创建的 DLL 的名称。 main1() 是我希望从我的 C# 代码中执行的方法。现在,从我的 C# 代码中,我调用了 main1();方法,我得到一个错误 DLL not found exception,但 DLL 在 bin\Debug 文件夹中。我该如何解决这个问题。注意:这就是我添加 DLL 的方式,R-Click 项目并添加引用 --> 选择 DLL【参考方案3】:
您需要阅读 P/Invoke aka pinvoke aka "Platform Invoke":
http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx
【讨论】:
是的,我已经阅读了几个关于此的教程,但我不明白 public static extern 是什么意思。我无法编辑使用 Visual C++ 编写的 C 代码。无论如何,我将代码作为 DLL 文件。例如考虑以下代码段;void main() printf("HELLO WORLD");
以上是我的 C 代码,现在它是一个 DLL,我如何从我的 C# Main() 方法访问这个 main()。我基本上想执行 main() (我的 c 代码)中的内容。救命!
@illep:如果你不能修改你的 DLL,那么你就不走运了——必须导出函数才能从外部世界访问它们。如果您的 DLL 是伪装的 EXE(具有工作的 main
函数),您可以使用 System.Diagnostics.Process.Start
执行该 DLL,我猜。
@Pierre 是的,我已经尝试过了,但我不想打开控制台。有没有办法避免这种情况?
@illep:是的,您可以在隐藏模式下启动控制台应用程序(使用ProcessStartInfo
并指定WindowStyle = ProcessWindowStyle.Hidden
)。以上是关于从 C# 程序访问 DLL 中的方法的主要内容,如果未能解决你的问题,请参考以下文章
MFC dll 中的访问冲突(用 C++/CLI 包装)从 C# 程序开始