2

I'm in need to call an function that return an structure that contains an int and an vector of other structures in C# for a windows ce 6.0 project:

The function is provided by an 3rd party provider (Chinese manufacturer of the pda), and they only delivered me the .h files, the dll and lib.

The function i'm trying to call in C# is defined in the .h file as :

DLLGSMADAPTER ApnInfoData* GetAvailApnList();

the ApnInfoData structure is as follows:

typedef struct ApnInfoData
{
    int m_iDefIndex;
    ApnInfoArray m_apnList;
}

typedef struct ApnInfo
{
    DWORD m_dwAuthType;
    TCHAR m_szName[64];
    TCHAR m_szTel[32];
    TCHAR m_szUser[32];
    TCHAR m_szPassword[32];
    TCHAR m_szApnName[32];
}*LPAppInfo;

typedef vector<ApnInfo> ApnInfoArray;

the DLLGSMADAPTER is a

#define DLLGSMADAPTER _declspec(dllexport)

My question is how can i pinvoke this function in the .net cf, since it uses the vector class, and i don't know how to marshal this.

2 Answers 2

3

This is not possible. P/Invoke is designed to marshal C types only. You have a few options:

  • Use C++/CLI to build a managed wrapper around your C library and then use it from C#
  • Write a C wrapper around your C++ types and then P/Invoke the C wrapper
  • Write a COM wrapper around the C++ types and then generate a com-interop stub.

The most basic C wrapper around this would go something like this:

// creates/loads/whatever your vector<ApnInfo> and casts it to void*, and then returns it through 'handle'
int GetAppInfoHandle(void **handle);

// casts handle back to vector<ApnInfo> and calls .size()
int GetAppInfoLength(void *handle);   

// Load into 'result' the data at ((vector<ApnInfo>*)handle)[idx];
void GetAppInfo(void *handle, int idx, ApnInfo *result);  
Sign up to request clarification or add additional context in comments.

3 Comments

So i have to create an c wrapper that exports this functions and call the GetAppInfo for each element to retrieve the info i need, of course i have to call the others to have the handle and number of elements before i call the GetAppInfo. Thank you for your quick answer
Sure, something like that. The key is that C++ doesn't marshal across language barriers very well at all. The types are too complex and the C++ type itself does not describe the actual layout of memory within vector<>. P/Invoke can deal with C types, and since C++ can pretend to be C... you get the idea.
Although it is being marked as a correct answer. it seems to me that C++/CLI is not available on Windows CE.
1

Wrapping a std::vector<your_struct> in C# is possible with just regular P/Invoke Interop, it is complicated though.

The basic idea of instantiating a C++ object from .NET world is to allocate exact size of the C++ object from .NET, then call the constructor which is exported from the C++ DLL to initialize the object, then you will be able to call any of the functions to access that C++ object, if any of the method involves other C++ classes, you will need to wrap them in a C# class as well, for methods with primitive types, you can simply P/Invoke them. If you have only a few methods to call, it would be simple, manual coding won't take long. When you are done with the C++ object, you call the destructor method of the C++ object, which is a export function as well. if it does not have one, then you just need to free your memory from .NET.

Here is an example.

public class SampleClass : IDisposable
{    
    [DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi,          CallingConvention=CallingConvention.ThisCall)]
    public extern static void SampleClassConstructor(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject, int x);

    IntPtr ptr;

    public SampleClass(int sizeOfYourCppClass)
    {
        this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
        SampleClassConstructor(this.ptr);  
    }

    public void DoSomething()
    {
        DoSomething(this.ptr);
    }

    public void DoSomethingElse(int x)
    {
        DoSomethingElse(this.ptr, x);
    }

    public void Dispose()
    {
        Marshal.FreeHGlobal(this.ptr);
    }
}

For the detail, please see the below link,

C#/.NET PInvoke Interop SDK

(I am the author of the SDK tool)

6 Comments

Why? I appreciate if you can give the detail. Thanks!
I did a quick research and I did not found anything prevent developers from creating a std::vector object from C# and calling into the function via regular P/Invoke Interop using Compact Framework. Can you explain further? Thanks!
To instantiate a std::vector object and call into the C++ object, we only need to allocate memory for the C++ std::vector, and call the constructor of std::vector to initialize the object and then you can call any functions of the std::vector class exported the DLL.
I went ahead and read a couple of books about Marshal class in the compact framework, a few of the static marshal methods are missing in the compact version, none of those missing methods prevents from using this solution to wrap a C++ class, so the statement of that it does not apply to compact framework is not correct. I will improve our C# wrapper generator to support the compact framework as well.
While I am working on the compact framework version, I found there is limit on windows CE, passing floating point value type to windows CE DLL via compact framework is not supported, the workaround is to add an alternative method of the original one which passes value type of floating type by passing an reference to a floating type value.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.