通过损坏的名称 P/调用函数

发布于 2024-10-14 12:16:20 字数 2815 浏览 4 评论 0原文

我试图在 windows ce 6.0 环境中调用 .net cf 3.5 中非托管 c++ dll 中的函数。

结构体定义为:

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

    }

我缺少什么才能使其工作。

更新

新的.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);

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£ºGSM 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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浊酒尽余欢 2024-10-21 12:16:20

您只能调用已导出为 C 样式函数的函数。据我所知,您不能通过 P/Invoke 直接调用 C++ 函数,例如:

如何设置 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);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文