嵌入标准C++;进入.NET应用程序 我想在标准的、平台无关的C++中编写算法库。 我可以接受相同的C++代码,并将其编译为.NET,以便C语言应用程序可以使用该库吗? 如果不是,实现这种互操作的最简单的方法是什么? < P>不能直接在C语言和标准C++之间进行接口。但是,您可以在C++ /CLI包装器中使用C++库,这使得.NET托管代码中的功能可用性(因此C<)。 简单地将包装器写为C++ .CLI库,它公开了.NETAPI并包含了来自标准C++库的代码(但不幸的是,据我所知,这不能静态链接)。您有三种方法来将库暴露为易于从托管代码调用: 为它编写一个C++/CLI包装,其中包含一个公共ref类——C#代码将调用此类的方法,该类将调用库的本机方法 将库中的C风格函数作为DLL公开-C代码将使用P/Invoke调用该函数 在C++中编写一个COM组件,它使用你的库并通过添加一个COM引用来从C代码中调用它。

嵌入标准C++;进入.NET应用程序 我想在标准的、平台无关的C++中编写算法库。 我可以接受相同的C++代码,并将其编译为.NET,以便C语言应用程序可以使用该库吗? 如果不是,实现这种互操作的最简单的方法是什么? < P>不能直接在C语言和标准C++之间进行接口。但是,您可以在C++ /CLI包装器中使用C++库,这使得.NET托管代码中的功能可用性(因此C<)。 简单地将包装器写为C++ .CLI库,它公开了.NETAPI并包含了来自标准C++库的代码(但不幸的是,据我所知,这不能静态链接)。您有三种方法来将库暴露为易于从托管代码调用: 为它编写一个C++/CLI包装,其中包含一个公共ref类——C#代码将调用此类的方法,该类将调用库的本机方法 将库中的C风格函数作为DLL公开-C代码将使用P/Invoke调用该函数 在C++中编写一个COM组件,它使用你的库并通过添加一个COM引用来从C代码中调用它。,.net,visual-c++,c++-cli,interop,managed-c++,.net,Visual C++,C++ Cli,Interop,Managed C++,第三个,COM,我只是为了完整性才加入的。这不是我的第一选择。或者我的第三个。如果COM组件存在是一回事,那么仅仅为此编写它又是另一回事 在前两者之间,问题在于还有谁可以使用这个库。如果C#代码是唯一使用它的代码,那么做你喜欢的。但例如,您可能有15或20个本机方法来设置各种属性,然后是执行实际工作的go或execute方法。因为托管本机互操作有成本,我会告诉您编写一个C++/CLI函数,该函数包含20个参数,调用各种本机函数,然后调用go或execute。这为您提供了一个更简洁的界面,而不是闲

第三个,COM,我只是为了完整性才加入的。这不是我的第一选择。或者我的第三个。如果COM组件存在是一回事,那么仅仅为此编写它又是另一回事


在前两者之间,问题在于还有谁可以使用这个库。如果C#代码是唯一使用它的代码,那么做你喜欢的。但例如,您可能有15或20个本机方法来设置各种属性,然后是执行实际工作的
go
execute
方法。因为托管本机互操作有成本,我会告诉您编写一个C++/CLI函数,该函数包含20个参数,调用各种本机函数,然后调用
go
execute
。这为您提供了一个更简洁的界面,而不是闲聊,并降低了互操作成本。

您可以使用pinvoke从任何.NET语言调用本机C/C++库。这里是一个快速教程。您还可以在C++中创建COM DLL,以便使用COM互操作直接从C内引用。除非您需要COM的优势,否则pinvoke是一条更容易的途径

当然,正如Konrad所言,使用托管C++解决方案包装C++ DLL。 例如,查看有关如何从C#调用win32 api的示例

从上面的MSDN链接(根据下面的注释进行修改):


你可以调用本地C库,C++库假装是C库。你不能把#包括在内然后从C#那里得到破解。我从来没有说过你可以。最初的问题是如何与本机库进行互操作。我提出的解决方案是完全有效的。您的P/Invoke签名不正确--
put
\u flushall
是使用
\uu cdecl
调用约定导出的,但是
DllImport
属性使用
\uu stdcall
,除非您另有指定。(我知道这个错误是从你链接到的MSDN页面复制的,但你最好在这里修复它。)@ildjarn:谢谢你提供的信息。我四处查看,有趣的是,任何地方都没有任何示例显示使用这两种方法指定的调用约定(至少我看到过)。我使用两种调用约定测试了示例代码,两种约定都有效。我将修改答案,使其具有适当的约定。这会影响性能吗?在某些平台上,CLR会抛出一个关于堆栈不平衡的异常,在其他平台上,它能够自动纠正不平衡。我怀疑更正不是免费的。。。关于显示调用约定,这里要说明的是它没有显示的事实——C/C++的默认值是
\uuu cdecl
,而.NET P/Invoke的默认值是
\uu stdcall
,如果在任何一方都没有指定,那么默认值必须起作用。
using System;
using System.Runtime.InteropServices;

class PlatformInvokeTest
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int puts(
        [MarshalAs(UnmanagedType.LPStr)]
        string m);
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern int _flushall();


    public static void Main() 
    {
        puts("Hello World!");
        _flushall();
    }
}