编写托管包装的非托管(C ++)code - 自定义类型/结构自定义、类型、结构、code

2023-09-04 12:17:46 作者:陪妳花開花落

faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(
       faacEncHandle hEncoder);

我试图想出了一个简单的包装,这个C ++库;我从来不是很简单的p做得更多/前调用互操作 - 就像与基本参数一个函数调用

I'm trying to come up with a simple wrapper for this C++ library; I've never done more than very simple p/invoke interop before - like one function call with primitive arguments.

因此​​,考虑到上面的C ++函数,例如,我应该怎么办,处理返回类型和参数?

So, given the above C++ function, for example, what should I do to deal with the return type, and parameter?

FAACAPI定义为:的#define FAACAPI __stdcall

FAACAPI is defined as: #define FAACAPI __stdcall

faacEncConfigurationPtr定义:

faacEncConfigurationPtr is defined:

typedef struct faacEncConfiguration
{
    int version;
    char *name;
    char *copyright;
    unsigned int mpegVersion;
    unsigned long bitRate;
    unsigned int inputFormat;
    int shortctl;

    psymodellist_t *psymodellist;

    int channel_map[64]; 

} faacEncConfiguration, *faacEncConfigurationPtr;

AFAIK这意味着该函数的返回类型是一个引用这个结构?

AFAIK this means that the return type of the function is a reference to this struct?

和faacEncHandle是:

And faacEncHandle is:

typedef struct {
    unsigned int numChannels;
    unsigned long sampleRate;
...
    SR_INFO *srInfo;
    double *sampleBuff[MAX_CHANNELS];
...
    double *freqBuff[MAX_CHANNELS];
    double *overlapBuff[MAX_CHANNELS];

    double *msSpectrum[MAX_CHANNELS];

    CoderInfo coderInfo[MAX_CHANNELS];
    ChannelInfo channelInfo[MAX_CHANNELS];
    PsyInfo psyInfo[MAX_CHANNELS];
    GlobalPsyInfo gpsyInfo;
    faacEncConfiguration config;

    psymodel_t *psymodel;

    /* quantizer specific config */
    AACQuantCfg aacquantCfg;

 /* FFT Tables */
    FFT_Tables fft_tables;

    int bitDiff;
} faacEncStruct, *faacEncHandle;

这样结构中,我们看到了很多其他类型的...嗯。

So within that struct we see a lot of other types... hmm.

从本质上讲,我试图找出如何处理这些类型在我的托管包装? 我是否需要创建这些类型/结构的版本,在C#中?事情是这样的:

Essentially, I'm trying to figure out how to deal with these types in my managed wrapper? Do I need to create versions of these types/structs, in C#? Something like this:

[StructLayout(LayoutKind.Sequential)]
struct faacEncConfiguration
{
    uint useTns;
    ulong bitRate;
...
}

如果是的话,可以在运行时会自动地图这些对象上的海誓山盟? 而且,我也有,直到我得到的所有基本元素来打造这些映射类型在这些返回类型/参数类型层次结构的所有类型,一路下来?

If so then can the runtime automatically "map" these objects onto eachother? And, would I have to create these "mapped" types for all the types in these return types/parameter type hierarchies, all the way down until I get to all primitives?

我知道这是一个广泛的话题,就起床到快速了解什么,我需要学习如何做到这一点是非常AP preciated任何意见!谢谢!

I know this is a broad topic, any advice on getting up-to-speed quickly on what I need to learn to make this happen would be very much appreciated! Thanks!

推荐答案

您是在正确的轨道上,你将如何需要创建重新present unamanged结构有P用管理结构/ Invoke的。

Your are on the right track with how you would need to create managed structures that represent unamanged structures for use with P/Invoke.

然而不是互操作与非托管库的最佳策略,因为使用这个API从C#仍觉得像使用C API - 创建和初始化一个结构,它传递给一个函数,并得到一些其他结构的回报。

It is however not the best strategy for interop with unmanaged libraries, because using this API from C# would still feel like using a C API - create and initialise a structure, pass it to a function and get some other structure in return.

这是正常使用的P / Invoke为奇函数调用未以其他方式公开为.NET API,但对于一个完全成熟的API包装我会强烈建议使用托管C ++(C ++ / CLI)。这是在创造非托管互操作层的.NET绝对是无与伦比的。

It is OK to use P/Invoke for an odd function call that is not otherwise exposed as .NET API, but for a full blown API wrapper I would highly recommend using managed C++(C++/CLI). It is absolutely unparalleled in creating unmanaged interop layers for .NET.

最大的挑战是将其转换基本上C接口进入,你调用方法关闭对象的面向对象的接口,而不是调用全局函数与所有公共成员的结构。

The biggest challenge would be to convert this essentially C interface into an object orientated interface where you call methods off objects, as opposed to calling global functions with structures of all-public members.

当你开始写详细的结构图的的P / Invoke,你将自己不得不面对相当多的神奇控制如何管理的基本数据类型转换成非托管类型。通常情况下,使用不正确类型将导致运行时错误。

As you start writing elaborate structure graphs for P/Invoke you would yourself having to deal with quite a bit of "magic" that governs how managed primitive types convert to unmanaged types. Often, using incorrect types will cause a run-time error.

使用托管C ++(IJW - 它只是工作)。你定义管理结构,类在C接口++,它允许更自然的使用基础库和更原生的界面到您的C#应用​​程序的

With managed C++ (IJW - It Just Works) you define managed structures, classes, interfaces in C++, which allows more natural use of the underlying library and a more native interface to your C# application.

这是C ++ / CLI一个很好的概述。另外MSDN对所有托管C ++功能丰富的文档。

This is a great overview of C++/CLI. Also MSDN has extensive documentation for all managed C++ features.