简体   繁体   中英

C++ to C# wrapping - how to handle array of double pointers from C#

I've been browsing this site for a long time & taking grateful advantage of your answers to other peoples' questions - now, alas, I have to reveal my ignorance by asking one of my own. I searched for an existing equivalent but couldn't find one; I apologize if this is a duplicate.

I'm attempting to use an unmanaged Windows DLL (the Intel Power Gadget 3.0 API, FWIW) from a Visual C# Winforms app under the .Net 4.0 framework. The API is written with C++ implementations in mind, so I'm having to translate as I go. I've been able to wrap and implement most of the functions of the library, but am flummoxed by this one:

bool GetPowerData(int iNode, int iMSR, double *pResult, int *nResult);

...which is described by the authors thus (my emphasis):

Returns the data collected by the most recent call to ReadSample(). The returned data is for the data on the package specified by iNode, from the MSR specified by iMSR. The data is returned in pResult, and the number of double results returned in pResult is returned in nResult. Refer Table 1: MSR Functions.

( https://software.intel.com/en-us/blogs/2014/01/07/using-the-intel-power-gadget-30-api-on-windows )

Key point: the function returns its main data in the form of a pointer to an array of doubles - or is it an array of pointers to doubles? ...What level of indirection? This is where it all starts to get uncertain for me! :)

At least some of the input parameters are simple; iNode and iMSR are int s, the value of which I know and can already obtain.

I've declared the function in my C# code with this signature:

[DllImport("EnergyLib32.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern bool GetPowerData(int iNode, int iMSR, out IntPtr pResult, ref int nResult);

(I'm sure that's my first mistake, right there.)

As for actually invoking the function, I've tried various possibilities, all too ugly to even show here.

Could someone with greater knowledge than mine please suggest the best way to handle this function and its return value?

Thank you in advance.

That documentation is unclear. Since it's a double * to be filled with multiple results, you are being required to pass in a preallocated array -- but how big should that array be? The doc says the following:

An MSR's function, which the API obtains from GetMsrFunc(), determines the amount and meaning of data returned from GetPowerData() as described in Table 1.

And in Table 1 we see:

  • MSR 0: 1 double.
  • MSR 1: 3 doubles.
  • MSR 2: 2 doubles.
  • MSR 3: 1 double.

So, an array of 3 doubles should be enough to hold all possible return data. This is borne out by the sample c++ source which does

        for (int j = 0; j < numMsrs; j++)
        {
            int funcID;
            energyLib.GetMsrFunc(j, &funcID);
            double data[3];
            int nData;
            wchar_t szName[MAX_PATH];

            energyLib.GetPowerData(currentNode, j, data, &nData);
            energyLib.GetMsrName(j, szName);

So you would declare it like:

    [DllImport("EnergyLib32.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern bool GetPowerData(int iNode, int iMSR, [In, Out] double [] pResult, out int nResult);

And to call it, use a

    double [] result = new double[3];

See here for a discussion of passing arrays to unmanaged code.

(Note - answer not tested.)

The correct answer (in the sense that it worked for me - YMMV! - was posted by DBC, promptly and with clarity. Here's what I used, based on DBC's comments:

Declaration:

[DllImport("EnergyLib64.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern bool GetPowerData(int iNode, int iMSR, [In, Out] double[] pResult, out int nResult);

And usage:

double[] result = new double[4];
....
bResult = GetPowerData(0, iModeLocal, result, out nResult); // where iModeLocal is an integer that determines the type of data (MSR) I'm interested in

My only reason for not marking this as "answered" a long time ago is that I didn't realize I hadn't. Whoops. Sorry.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM