Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
565 views
in Technique[技术] by (71.8m points)

c# - P/Invoking function via a mangled name

I'm trying to call an function in an unmanaged c++ dll in .net cf 3.5 in a windows ce 6.0 environment.

The struct is defined as:

typedef struct TagOperatorInfo
{
    DWORD dwMode;       
    DWORD dwFormat;     //Operator name format
    DWORD dwAct;        //Network type(Available in 3G module£oGSM or 3G),
    TCHAR szOper[32];   
}OperatorInfo,*LPOperatorInfo;

and the function call is:

BOOL GetCurOperatorInfo(LPOperatorInfo pinfo);

I defined in .net the TagOperatorInfo as follows:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public struct TagOperatorInfo
    {

        /// DWORD->unsigned int
        public uint dwMode;

        /// DWORD->unsigned int
        public uint dwFormat;

        /// DWORD->unsigned int
        public uint dwAct;

        /// TCHAR[32]
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 32)]
        public string szOper;
    }

and after seeing some articles and msdn documentation i call the native function as:

[System.Runtime.InteropServices.DllImportAttribute(gsmaAdapterDLLName, EntryPoint = "#30", CallingConvention = CallingConvention.Winapi)]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
    internal static extern bool GetCurOperatorInfo([MarshalAs(UnmanagedType.LPStruct)] ref NativeHelper.TagOperatorInfo operatorInfo);

Note: I call the function with an entry point defined with the ordinal because the c++ mangled names.

The problem that i have is that i always get the notSupportedException throw. I don't understand because the ref parameter should give it the Pointer to the struct.

My .net function that calls it is:

/// <summary>
    /// Gets the current operator information.
    /// </summary>
    /// <param name="operatorInfo">The operator info.</param>
    /// <returns></returns>
    public static bool GetOperatorInformation(out NativeHelper.TagOperatorInfo operatorInfo)
    {
        operatorInfo = new NativeHelper.TagOperatorInfo();

        if (NativeImports.GetCurOperatorInfo(ref operatorInfo) == true)
        {
            return true;
        }
        else
        {
            return false;
        }

    }

What i'm missing for this to work.

UPDATE

New .Net Compact Framework method call

[System.Runtime.InteropServices.DllImportAttribute(gsmaAdapterDLLName, EntryPoint = "?GetCurOperatorInfo@CGSMAdapter@@YAHPAUTagOperatorInfo@@@Z", CallingConvention = CallingConvention.Winapi)]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
    internal static extern bool GetCurOperatorInfo([MarshalAs(UnmanagedType.LPStruct)]ref NativeHelper.TagOperatorInfo operatorInfo);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can only call functions that have been exported as C style functions. As far as I am aware you cannot call straight C++ functions via P/Invoke, e.g.:

How to set up a C++ function so that it can be used by p/invoke?

Update

Actually, it does appear you can use mangled names when calling a function via P/Invoke. This is something I could never get working in the past, so I stand corrected. Using names rather than ordinals should be more resilient too:

Reference: Entry Point Not Found Exception

So something like:

[DllImport(gsmaAdapterDLLName,
    EntryPoint="?GetCurOperatorInfo@CGSMAdapter@@YAHPAUTagOperatorInfo@@@Z", 
    ExactSpelling = true,
    CallingConvention = CallingConvention.Cdecl)]
public static extern bool GetCurOperatorInfo(out TagOperatorInfo info);

And for .Net CF:

DllImport(gsmaAdapterDLLName,
    EntryPoint="?GetCurOperatorInfo@CGSMAdapter@@YAHPAUTagOperatorInfo@@@Z", 
    CallingConvention = CallingConvention.WinApi)]
public static extern bool GetCurOperatorInfo(out TagOperatorInfo info);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...