天道酬勤,学无止境

DllImport Unmanaged, Non .NET Dll to .NET Project 代表 Char * 和 Void __StdCall(DllImport Unmanaged, Non .NET Dll to .NET Project Representing Char * and Void __StdCall)

问题

我有一个非 .net 和非托管的 DLL,我需要导入它用 Borland C++ 编写。 它返回 void 并在函数上具有标识符 __stdcall。 它还需要传递 char *。 当我在 VS 2005 中尝试将它添加为对我的项目的引用时,它返回无效程序集的错误。

我怎样才能在 C# 中做到这一点?

这是我目前拥有的,但不起作用:

[DllImport ("Project1.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern IntPtr CustomerForm
        (String caption);
回答1

对于非托管 DLL,您不要将其添加为引用。 确保二进制 DLL 与 .NET EXE 项目所在的构建位于同一文件夹中,通常位于 {project}\bin\debug。

另外,当您使用 Borland C++ 构建非托管 DLL 时,请确保您有一个用于导出的 .DEF 文件。

编辑:

LIBRARY Project1
EXPORTS
    CustomerForm

并在您的 Borland C++ 源代码中确保将函数声明为导出,例如:

#ifdef __cplusplus
__declspec(dllexport) void CustomerForm(char *s);
#endif

使用这将确保该函数是可导出的并且可以链接!

确保您的 DllImport 属性的签名与您的本机 C++ Dll 的签名相匹配,即

[DllImport ("Project1.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern void CustomerForm(string caption);

希望这会有所帮助,最好的问候,汤姆。

回答2

要使用 DllImport,您不需要添加 dll 的引用,只需将 dll 放在您的可执行文件旁边或在 system32 中,它应该可以工作。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • DllImport Unmanaged, Non .NET Dll to .NET Project Representing Char * and Void __StdCall
    I have a DLL non .net and unmanaged written in Borland C++ that I need to import. It returns void and has the identifier __stdcall on the function. It also requires passing of char *. When I try to add it as a reference to my project in VS 2005, it returns an error of not valid assembly. How can I do this in C#? This what I currently have and it does not work: [DllImport ("Project1.dll", CallingConvention=CallingConvention.StdCall)] public static extern IntPtr CustomerForm (String caption);
  • 在 c# 代码中使用在 c++ dll 中定义的类(using a class defined in a c++ dll in c# code)
    问题 我有一个用C ++编写的dll,我需要在我的C#代码中使用此dll。 搜索之后,我发现使用P / Invoke可以访问所需的函数,但是这些函数是在类中定义的,并且使用非静态私有成员变量。 因此,我需要能够创建此类的实例以正确使用这些功能。 如何获得对此类的访问权限,以便可以创建实例? 我一直无法找到一种方法来做到这一点。 我想我应该注意,c ++ dll不是我的代码。 回答1 无法在C#代码中直接使用C ++类。 您可以间接使用PInvoke来访问您的类型。 基本模式是为Foo类中的每个成员函数创建一个关联的非成员函数,该非成员函数调用该成员函数。 class Foo { public: int Bar(); }; extern "C" Foo* Foo_Create() { return new Foo(); } extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); } extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; } 现在只需将这些方法调用到您的C#代码中即可 [DllImport("Foo.dll")] public static extern IntPtr Foo_Create(); [DllImport("Foo.dll")] public
  • 如何实现从非托管DLL到.net应用程序的回调接口?(Howto implement callback interface from unmanaged DLL to .net app?)
    问题 在我的下一个项目中,我想为C ++中已经存在的代码实现GUI。 我的计划是将C ++部分包装在DLL中,并在C#中实现GUI。 我的问题是我不知道如何实现从非托管DLL到托管C#代码的回调。 我已经用C#进行了一些开发,但是托管代码和非托管代码之间的接口对我来说是新的。 有人可以给我一些提示或阅读技巧,还是一个简单的示例作为开始? 不幸的是,我找不到任何有用的东西。 回答1 您不需要使用Marshal.GetFunctionPointerForDelegate(),P / Invoke编组器会自动执行此操作。 您需要在C#端声明一个委托,该委托的签名与C ++端的函数指针声明兼容。 例如: using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; class UnManagedInterop { private delegate int Callback(string text); private Callback mInstance; // Ensure it doesn't get garbage collected public UnManagedInterop() { mInstance = new Callback(Handler)
  • When GC.KeepAlive(this) is needed when doing P/Invoke on unmanaged resources?
    I have a TestNet wrapper for a native component. The native component exposes a blocking TestNative::Foo() that communicates with managed part through calling managed callbacks and a weak GCHandle that is used to retrieve the reference to the .NET wrapper and provides a context. The GCHandle is weak since the .NET wrapper is meant to hide the fact that is handling unmanaged resources to user and deliberately doesn't implement the IDisposable interface: being non weak it would prevent TestNet instances from being collected at all, creating a memory leak. What's happening is that in Release
  • 托管C ++以在C#和C ++之间架起桥梁(Managed C++ to form a bridge between c# and C++)
    问题 我有点生疏,实际上对我的C ++生疏了。 自大学一年级以来没有碰过它,所以已经有一段时间了。 无论如何,我所做的与大多​​数人的做法相反。 从C ++调用C#代码。 我已经在网上进行了一些研究,似乎需要创建一些托管的C ++来架起桥梁。 使用__declspec(dllexport),然后从中创建一个dll,并将整个对象用作包装器。 但是我的问题是-我真的很难找到例子。 我找到了一些基本的东西,有人想将C#版本用于String.ToUpper(),但这是非常基本的,只是一小段代码。 有人对我在哪里可以找到更具体的东西有任何想法吗? 注意,我不想使用COM。 目的是完全不接触C#代码。 回答1 尽管lain击败了我写一个例子,但我还是会贴出来,以防万一... 编写包装程序以访问您自己的库的过程与访问标准.Net库之一相同。 一个名为CsharpProject的项目中的示例C#类代码: using System; namespace CsharpProject { public class CsharpClass { public string Name { get; set; } public int Value { get; set; } public string GetDisplayString() { return string.Format("{0}: {1}"
  • 如何从标准的非托管非.NET应用程序调用C ++ / CLI(.NET)DLL?(How do I call C++/CLI (.NET) DLLs from standard, unmanaged non-.NET applications?)
    问题 在不受管的世界中,我能够编写__declspec(dllexport),或者使用.DEF文件公开能够调用DLL的函数。 (由于在C ++中对__stdcall进行名称处理,我将别名放入.DEF文件中,以便某些应用程序可以重新使用某些导出的DLL函数。)现在,我感兴趣的是能够从目录中公开单个入口点函数。 .NET程序集,采用非托管方式,但已将其输入DLL中的.NET样式的函数中。 是否有可能以简单直接的方式进行? 我所拥有的是一个第三方程序,该程序已通过实现某些复杂数学功能的DLL(插件)扩展。 但是,第三方程序对我而言没有办法可视化计算结果。 我想以某种方式使用这些预先编写的数学函数,将它们编译为单独的DLL(但在.NET中使用C ++ / CLI),然后将钩子添加到函数中,以便我可以呈现.NET幕后的内容。用户控制。 我不确定如何将.NET内容与非托管内容混合在一起,或者不确定Google如何完成此任务。 有关托管/非托管网桥的特定建议,或以我所描述的方式完成渲染的替代方法将很有帮助。 谢谢你。 回答1 好吧,C ++ / CLI编译器使它变得非常容易。 只需编写一个静态托管函数并使用__declspec(dllexport)对其赋予属性即可。 编译器会注入一个存根,该存根会自动加载CLR来执行托管代码。 这是一种可服务的方法,它不是很可扩展,而且不会很快。 下一步是使用
  • PInvoke DLL in C#
    I want to pass a structure to C function and I write the following code. When I run it, the first function - Foo1 is working and then function Foo gets an exception. Can you help me to understand what the problem is?... The C code: typedef struct { int Size; //char *Array; }TTest; __declspec(dllexport) void Foo(void *Test); __declspec(dllexport) int Foo1(); void Foo(void *Test) { TTest *X = (TTest *)Test; int i = X->Size; /*for(int i=0;i<Test->Size;Test++) { Test->Array[i] = 127; }*/ } int Foo1() { return 10; } The C# code: using System; using System.Runtime.InteropServices; using System
  • 将向量/数组从非托管C ++传递到C#(Passing a vector/array from unmanaged C++ to C#)
    问题 我想将100-10,000点从非托管C ++传递给C#。 C ++方面看起来像这样: __declspec(dllexport) void detect_targets( char * , int , /* More arguments */ ) { std::vector<double> id_x_y_z; // Now what's the best way to pass this vector to C# } 现在我的C#端看起来像这样: using System; using System.Runtime.InteropServices; class HelloCpp { [DllImport("detector.dll")] public static unsafe extern void detect_targets( string fn , /* More arguments */ ); static void Main() { detect_targets("test.png" , /* More arguments */ ); } } 为了将std :: vector及其所有内容从非托管C ++传递到C#,我该如何更改我的代码? 回答1 只要托管代码不调整向量的大小,就可以使用vector.data() (对于C ++ 0x)或&vector[0
  • 使用它的指针从托管C#中释放非托管内存(Release unmanaged memory from managed C# with pointer of it)
    问题 简而言之,问题是:如何释放托管代码中作为ItrPtr从本机DLL返回的内存? 详细信息:假设我们的简单函数将两个参数作为OUTPUT,第一个是字节数组的引用指针,第二个是Reference Int。 该函数将根据一些规则分配字节数,并返回内存的指针,字节的大小和返回值(1表示成功,0表示失败)。 下面的代码工作正常,我可以正确获取字节数组以及字节数和返回值,但是当我尝试使用指针(IntPtr)释放内存时,出现异常: Windows已在TestCppDllCall.exe中触发了一个断点。 这可能是由于堆损坏所致,这表明TestCppDllCall.exe或其已加载的任何DLL中存在错误。 这也可能是由于用户在TestCppDllCall.exe具有焦点时按下了F12。 输出窗口可能包含更多诊断信息。 为了清楚起见: 接下来的C#代码可以与具有相同签名的其他DLL函数一起正常工作,并且释放内存的工作没有任何问题。 如果需要更改分配存储方法或添加任何其他代码,则可以接受(C)代码的任何修改。 我需要的所有功能都是本机DLL函数通过引用接受两个参数(字节数组和int,在c#中[字节数组和int的IntPtr])根据某些规则用一些值填充它们并返回函数结果(成功或失败) 。 CppDll.h #ifdef CPPDLL_EXPORTS #define CPPDLL_API _
  • Passing byte array from C++ unmanaged dll to C# unity
    I am trying to return the byte array from my unmanaged c++ dll back to c# unity. Thank you very much in advance for taking the time to help >< I'm really new to DLL in unity so I'm extremely confused how 2 languages are even suppose to work together. CPP The problem is in here, I've done my calculations, but I'm struggling to find a way to return it back to c# with an array format. Currently, the byte array holds color codes e.g RGBA (223,124,23,255,212,143,234,255) and it repeats #include "WebcamDLL.h" #include <vector> extern "C" { int adjustBrightnesss(unsigned char* bytes, int sizeOfArray)
  • 非托管DLL无法在ASP.NET服务器上加载(Unmanaged DLLs fail to load on ASP.NET server)
    问题 此问题与ASP.NET网站有关,该网站最初在VS 2005中开发,现在在VS 2008中。 该网站使用了两个非托管外部DLL,它们不是.NET,而且我没有源代码来编译它们,而必须按原样使用它们。 该网站可以在Visual Studio中正常运行,可以正确定位和访问这些外部DLL。 但是,当网站发布在网络服务器上(运行IIS6和ASP.NET 2.0)而不是开发PC时,它无法定位和访问这些外部DLL,并且出现以下错误: Unable to load DLL 'XYZ.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) 外部DLL和包装它们的托管DLL以及网站的所有其他DLL一起位于网站的bin目录中。 搜索此问题表明,许多其他人似乎在从ASP.NET网站访问外部非.NET DLL时也遇到相同的问题,但是我还没有找到一种可行的解决方案。 我已经尝试了以下方法: 运行DEPENDS来检查依赖关系,以确保前三个位于路径的System32目录中,最后一个位于.NET 2框架中。 我将这两个DLL及其依赖项放到System32中,然后重新启动了服务器,但是网站仍然无法加载这些外部DLL。 已将ASPNET,IIS_WPG和IUSR(用于该服务器
  • 在C#应用程序中使用C ++类DLL(Using C++ Class DLL in C# Application)
    问题 我有一个非托管的C ++ DLL,它仅导出一个类(不是COM ...这只是一个简单的C ++类)作为其接口。 我想在C#中使用此类,但被告知不能仅将其导入C#中。 在我的C#应用​​程序中使用此类的正确方法是什么? 回答1 假设Foo类的简单方法: 创建一个C ++ / CLI项目,称为FooWrapper。 使FooWrapper依赖于非托管dll(但是通常情况下)。 创建一个托管类ManagedFoo,其中包含单个Foo *类型的私有实例字段。 在ManagedFoo中提供公共包装功能,这些功能会转发到基础实例字段。 可选(尽管推荐): 将参数从.net习惯用法(字符串等)转换为C ++习惯用法(std :: string或char *) 捕获非托管异常并抛出托管异常 然后,使您的C#代码依赖于FooWrapper项目/ dll,并确保非托管dll与其一起正确部署,该操作的方式取决于非托管dll,但通常在同一目录中就足够了。 如果函数不依赖于类的实例,则P / Invoke更为简单 回答2 对于单个类库来说,这个答案可能有点过头,但是SWIG是“包装” C / C ++类以供其他语言使用的很好的解决方案。 它与C#一起很好地工作。 参见http://www.swig.org/。 回答3 DllImport是您最好的选择。 有一些数据类型按摩,尤其是当您传递结构时
  • 非托管 DLL 函数的正确调用约定(Proper calling convention of unmanaged DLL function)
    问题 我正在尝试为 LibVLC DLL 库编写一个简单的超简单轻量级包装器。 我不需要访问太多,只需要播放暂停和停止媒体文件的能力。 我正在查看文档和我发现的另一个链接,它解释了旧版本的 LibVLC,但对于最新版本来说已经过时了。 我也尝试过 LibVLC.Net,但它也过时了,我无法在源代码中找到我正在寻找的内容以将其与我尝试导出的功能相匹配。 我正在尝试导出以下签名: libvlc_new (int argc, const char *const *argv) 说明: argc the number of arguments (should be 0) argv list of arguments (should be NULL) 这就是我正在尝试的方法。 [DllImport("libvlc", EntryPoint = "libvlc_new")] public static extern IntPtr New(Int32 argc, String[] argv); 描述表明它应该是一个数组,我认为问题是第二个参数。 我试过了: [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] String[] argv 根据此处,还有一些其他选项,例如此处建议的 String 和
  • 如何从C#调用C ++ / CLI?(How do I call C++/CLI from C#?)
    问题 I have a class implemented in C++ that's responsible for the arithmetic computation of the program, and an interface using WPF. I process the input with C# but then how can I use my C++ class? I've seen some comments about making a managed C++ wrapper class to interact with it, but I don't know where to start. Nor do I know how I'd go to compile it along with all the other code. I can't really find a tutorial on this, and the stuff google shows on managed C++ doesn't really seem helpful. Anything out there to help me out? This doesn't seem unreasonable to me. EDIT Tried m3rLinEz solution
  • 如何根据CPU架构使用正确的非托管DLL文件? (32/64位)(How to use the correct unmanaged DLL file according CPU architecture? (32 / 64 bits))
    问题 我必须使用来自ASP.NET站点的C ++ DLL文件。 该站点将托管在32位和64位环境中。 我有32位和64位版本的非托管DLL文件。 如何根据当前服务器体系结构从正确的方法中导入方法? 就像发布的人一样,这可以作为部署问题来处理。 我担心的是:使用此DLL文件的Web应用程序非常庞大,并且我们没有部署文档。 没有人会记得部署正确的DLL文件,因此我正在尝试从解决方案中消除人为因素:) 回答1 最简单的方法是在两个不同的目录中为两个本机库提供相同的文件名,然后根据位数调整应用程序DLL的搜索路径。 http://www.pinvoke.net/default.aspx/kernel32.setdll目录 回答2 要使编译器/框架完成大部分工作,您需要 具有多个构建“平台”(通常为x86,x64-删除AnyCPU) 为每个构建配置设置每个“平台目标”配置我们添加了条件编译符号__WIN32和__X64 根据平台列出功能的不同实现,如果需要同时安装两者,则包括不同的dll名称。 #if __WIN32 public delegate int Move(int target); [DllImport("my.dll", SetLastError = true, CharSet = CharSet.Auto)] #elif __X64 public delegate int
  • Release unmanaged memory from managed C# with pointer of it
    The question in short words is : How to free memory returned from Native DLL as ItrPtr in managed code? Details : Assume we have simple function takes two parameters as OUTPUT, The first one is Reference Pointer to byte array and the second one is Reference Int . The function will allocate amount of bytes based on some rules and return the pointer of memory and the size of bytes and the return value (1 for success and 0 for fail) . The code below works fine and I can get the byte array correctly and the count of bytes and the return value, but when I try to free the memory using the pointer
  • 为非托管C ++客户端创建WCF服务(Create WCF service for unmanaged C++ clients)
    问题 我需要让不受管理的Windows C ++客户端与WCF服务进行对话。 C ++客户端可以在Win2000及更高版本上运行。 我可以控制WCF服务和正在使用的C ++ API。 由于它是针对专有应用程序的,因此最好在可能的情况下使用Microsoft的东西,绝对不要使用GNU许可的API。 那些让它起作用的人,您可以分步介绍如何使其起作用吗? 到目前为止,我已经研究了以下选项: WWSAPI-不好,在Win 2000客户端上不起作用。 ATL Server,使用以下指南作为参考。 我按照概述的步骤操作(删除策略引用并展平WSDL),但是生成的WSDL仍然无法被sproxy使用 还有其他想法吗? 请仅在实际使用时才能回答。 Edit1 :对于任何我可能感到困惑的人,我深表歉意:我一直在寻找一种从没有安装.NET框架的客户端调用WCF服务的方法,因此不能使用基于.NET的帮助程序库,它必须是纯非托管C ++ 回答1 基本思想是用C#为您的客户端编写WCF代码(这样更容易),并使用C ++桥接dll来弥合非托管C ++代码和以C#编写的托管WCF代码之间的差距。 这是使用Visual Studio 2008和.NET 3.5 SP1的分步过程。 首先要做的是创建WCF服务和托管它的方法。 如果已经有了,请跳至下面的步骤7。 否则,请按照此处的步骤创建Windows NT服务。
  • PInvokeStackImbalance C#调用非托管C ++函数(PInvokeStackImbalance C# call to unmanaged C++ function)
    问题 切换到VS2010后,托管调试助手将显示有关从C#应用程序调用非托管C ++函数导致的堆栈不平衡的错误。 平常的怀疑者似乎并不是造成此问题的原因。 还有什么我应该检查的吗? VS2008构建的C ++ dll和C#应用程序从来没有问题,没有怪异或神秘的错误-是的,我知道这并不意味着什么。 以下是已检查的内容: dll名称正确。 入口点名称正确,并已通过depends.exe进行了验证-代码必须使用错误的名称,并且确实如此。 调用约定是正确的。 大小和类型似乎都是正确的。 字符集正确。 忽略错误后似乎没有任何问题,并且在调试器之外运行时也没有问题。 C#: [DllImport("Correct.dll", EntryPoint = "SuperSpecialOpenFileFunc", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true)] public static extern short SuperSpecialOpenFileFunc(ref SuperSpecialStruct stuff); [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  • 是否可以从C#.Net调用C函数(Is it possible to call a C function from C#.Net)
    问题 我有一个C库,想从C#应用程序中调用此库中的函数。 我尝试通过将C lib文件添加为链接器输入并将源文件添加为其他依赖项来在C lib上创建C ++ / CLI包装器。 有什么更好的方法可以实现这一点,因为不确定如何将C输出添加到c#应用程序中。 我的C代码- __declspec(dllexport) unsigned long ConnectSession(unsigned long handle, unsigned char * publicKey, unsigned char publicKeyLen); 我的CPP包装器- long MyClass::ConnectSessionWrapper(unsigned long handle, unsigned char * publicKey, unsigned char publicKeyLen) { return ConnectSession(handle, publicKey, publicKeyLen); } 回答1 该示例将针对Linux : 1)创建一个C文件libtest.c并包含以下内容: #include <stdio.h> void print(const char *message) { printf("%s\\n", message); } 那是printf的一个简单的伪包装器。
  • C#性能-使用不安全的指针代替IntPtr和Marshal(C# performance - Using unsafe pointers instead of IntPtr and Marshal)
    问题 问题 我正在将C应用程序移植到C#中。 C应用程序从第三方DLL调用了许多函数,因此我在C#中为这些函数编写了P / Invoke包装器。 这些C函数中的一些函数分配了我必须在C#应用程序中使用的数据,因此我使用了IntPtr ,Marshal.PtrToStructure和Marshal.Copy将本地数据(数组和结构)复制到托管变量中。 不幸的是,事实证明C#应用程序比C版本要慢得多。 快速性能分析表明,上述基于封送处理的数据复制是瓶颈。 我正在考虑通过重写C#代码以使用指针来加快它的速度。 由于我没有使用C#中不安全的代码和指针的经验,因此我需要有关以下问题的专家意见: 使用unsafe代码和指针代替IntPtr和Marshal ing有什么弊端? 例如,它在某种程度上更不安全(双关语)吗? 人们似乎更喜欢封送,但我不知道为什么。 使用指针进行P /调用真的比使用封送处理快吗? 大概可以提高多少速度? 我为此找不到任何基准测试。 范例程式码 为了使情况更清楚,我整理了一个小的示例代码(实际代码要复杂得多)。 我希望这个例子能说明我在谈论“不安全的代码和指针”与“ IntPtr and Marshal”时的意思。 C库(DLL) MyLib.h #ifndef _MY_LIB_H_ #define _MY_LIB_H_ struct MyData { int length