调用C#从非托管C ++传递或返回“复杂”类型

调用C#从非托管C ++传递或返回“复杂”类型

问题描述:

我在帮助如何使用复杂的对象作为返回值或作为参数传递给C#类方法暴露给非托管C ++作为COM组件

I'm after help on how to use complex objects either as return values or passed as parameters to C# class methods exposed to unmanaged C++ as COM components

这里是为什么:

我正在开发一个项目,我们有六个非托管C ++应用程序,每个应用程序都直接访问同一个Microsoft SQL Server数据库。我们希望能够以最小的变化使用MS-Sql / Oracle / MySql,并且我们决定实现通过WCF服务暴露的业务逻辑加数据层,以获得所需的灵活性。

I'm working on a project where we have half a dozen unmanaged C++ applications that each directly access the same Microsoft SQL Server database. We want to be able to use MS-Sql/Oracle/MySql with minimum changes and we've decided to implement a business logic plus data layer exposed via WCF services to get the required flexibility.

这个策略取决于能否使非托管C ++与WCF服务互操作。有很多方法可以做到这一点,但我想要遵循的策略是创建一个暴露为COM组件的C#程序集,它将作为C ++和WCF层之间的桥梁。这个C#汇编程序将作为COM组件加载到非托管C ++进程中。

This strategy hinges on being able to get the unmanaged C++ to interop with the WCF service. There are a number of ways to do this, but the strategy I want to follow is to create a C# assembly exposed as a COM component which will act as a bridge between C++ and the WCF layer. This C# assembly will be loaded into unmanaged C++ process as COM component.

C#桥组件将包含一个帮助类,它有许多方法来描述以前表示为直接sql或存储的proc调用在C ++代码。

The C# bridge assembly will contain a helper class which has a number of methods that describe the operations that were formerly expressed as direct sql or stored proc calls in the C++ code.

我有两个问题要解决

1)对于INSERT,我需要传递一个对象来表示要插入的实体。在非托管C ++方面,我已经知道其中一个实体有大约40个属性,必须将其转换为SQL - 我不想要一个C#方法与40个参数,我想传递一个对象;我不知道如何通过COM将C ++对象编组到C#中,所以我考虑在C#边定义一个Stuct,然后让Struct COM可见。

1) For an INSERT, I need to pass an object representing the entity to be inserted. On the unmanaged C++ side, the I already know that one of the entities has about 40 properties which have to make it into SQL - I don't want a C# method with 40 parameters, I want to pass an object; I don't know how to marshal a C++ object via COM into C#, so I thought about defining a Stuct on the C# side and then make the Struct COM visible.

2)如何返回SELECT this,that,other,...的结果。我看到两个例子。一个返回一个struct [],另一个返回每个列字段包含一个string []的单个结构体和一个int count成员描述其他成员数组的长度。

2) How to return the result of a "SELECT this, that, other, ... ". I've seen two examples. One returns a struct[] and another returns a single struct containing a string[] for each column field and an int count member describing the length of the other member arrays.

在C#方面,我认为这将是一个定义和暴露一些请求/响应结构,将用于传入/输出数据的情况。这些结构将需要用属性来装饰,这些属性导致它们的成员不作为优化的结果改变位置。并且结构成员可能需要用属性来装饰,这暗示了编组人员在COM中如何暴露成员。

On the C# side, I think it will be a case of defining and exposing a number of request/response structs which will be used to pass data in/out. These structs will need to be decorated with attributes that cause their members not to "change position" as a result of optimization. And the struct members may need to be decorated with the attribute that hints to the marshaller how the member should be exposed in COM.

然后我必须工作如何实例化和填充这些结构体,如从非托管C ++看到的COM对象,那么我必须在方法调用中传递它们并将它们作为返回值处理。

Then of course I'll have to work out how to instantiate and populate these structs as seen as COM objects from the unmanaged C++, then I'll have to pass them in method calls and process them as return values.

这是我最困难的部分;我Grok C ++和一些MFC / ATL,但COM下的C ++是一个整体额外的复杂性。任何推荐的书,博客,教程的参数传递和返回值处理的主题,我已经描述将是非常有益的确实。

This is the most difficult part for me; I grok C++ and some MFC/ATL but COM under C++ is a whole extra level of complexity. Any recommended books, blogs, tutorials on the subject of parameter passing and return value processing as I've described would be very helpful indeed.

如果可能,我会把COM带入画面。如果你控制C ++代码(听起来像你这样做),应该更容易添加一个C ++ / CLI cpp文件,调用你的C#代码。 C ++ / CLI可以直接访问和创建托管和非托管类型,并在它们之间复制。

If possible, I'd avoing bringing COM into the picture. If you control the C++ code (it sounds like you do), it should be easier to add a single C++/CLI cpp file that calls into your C# code. C++/CLI can directly access and create managed and unmanaged types and copy between them.