P / вызывая функцию через искаженное имя - PullRequest
2 голосов
/ 26 января 2011

Я пытаюсь вызвать функцию в неуправляемой dll c ++ в .net cf 3.5 в среде windows ce 6.0.

Структура определяется как:

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

и вызов функции:

BOOL GetCurOperatorInfo(LPOperatorInfo pinfo);

Я определил в .net TagOperatorInfo следующим образом:

[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;
    }

и после просмотра некоторых статей и документации MSDN я вызываю нативную функцию как:

[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);

Примечание: я вызываю функцию с точкой входа, определенной ординалом, потому что имена c ++ искажены.

Проблема в том, что я всегда получаю исключение notSupportedException. Я не понимаю, потому что параметр ref должен дать ему указатель на структуру.

Моя функция .net, которая вызывает ее:

/// <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;
        }

    }

Чего мне не хватает, чтобы это сработало.

UPDATE

Новый .Net Compact Framework вызов метода

[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);

1 Ответ

7 голосов
/ 26 января 2011

Вы можете вызывать только те функции, которые были экспортированы как функции стиля C. Насколько я знаю, вы не можете вызывать прямые функции C ++ через P / Invoke, например ::10000

Как настроить функцию C ++, чтобы она могла использоваться p / invoke?

Обновление

На самом деле, похоже, что вы можете использовать искаженные имена при вызове функции через P / Invoke. Это то, с чем я никогда не мог работать в прошлом, поэтому я поправляюсь. Использование имен вместо ординалов также должно быть более гибким:

Ссылка: Точка входа не найдена, исключение

Так что-то вроде:

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

А для .Net CF:

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