.NetcompactFramework(Windows CE) 中的封送 char *

发布于 2024-12-14 18:14:41 字数 777 浏览 1 评论 0原文

我有来自 c++ 的以下签名

IDTECHREADER_EXPORTS void ReadTwoBlocks(char *pathConfig, 
    char *datablock1, char *datablock2, int timeout, bool &ret )

我能够在完整的 .NetFrameWork 上正确地编组它,它的工作原理如下

[DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks" )]
private static extern void _ReadTwoBlocks(
   [In][MarshalAs(UnmanagedType.LPStr)] string pathConfig,
   [Out][MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock1, 
   [Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock2,
   int TimeOut,
   ref bool result);

但是使用与上面相同的编组在 NetcompactFramework(Windows CE) 上不起作用,它会给出错误“NotSupported Exception”

我们如何正确编组上述 C++ 方法签名,以便它能够在 .NET CompactFramework(windows CE) 上正常工作,

任何想法都值得赞赏...谢谢。

I have the following signature from c++

IDTECHREADER_EXPORTS void ReadTwoBlocks(char *pathConfig, 
    char *datablock1, char *datablock2, int timeout, bool &ret )

I was able to Marshal this correctly on the Full .NetFrameWork and it works as below

[DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks" )]
private static extern void _ReadTwoBlocks(
   [In][MarshalAs(UnmanagedType.LPStr)] string pathConfig,
   [Out][MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock1, 
   [Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock2,
   int TimeOut,
   ref bool result);

However using the same Marshaling as above doesn't work on the NetcompactFramework(Windows CE) it gives an error "NotSupported Exception"

How do we correctly Marshal the above C++ method signature so that it will work correctly on the .NET CompactFramework(windows CE)

any ideas are apperciated...thanks.

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

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

发布评论

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

评论(2

故笙诉离歌 2024-12-21 18:14:51

它会是这样的:

[DllImport("IDTechReader.dll")]
private static extern void ReadTwoBlocks(IntPtr pathConfig, 
                IntPtr datablock1, IntPtr datablock2, int timeout, ref bool ret);

当你像这样使用它时:

string pathConfig = "..\program.ini";
IntPtr ptrPathConfig = IntPtr.Zero;
ptrPathConfig = Marshal.StringToHGlobalAnsi(pathConfig);
IntPtr ptrDatablock1 = IntPtr.Zero;
IntPtr ptrDatablock2 = IntPtr.Zero;
int timeout = 300;
bool ret = false;
ReadTwoBlocks(ptrPathConfig, ptrDatablock1, ptrDatablock2, timeout, ref ret);

string db1 = Marshal.PtrToStringAnsi(ptrDatablock1);
string db2 = Marshal.PtrToStringAnsi(ptrDatablock2);

It would be something like this:

[DllImport("IDTechReader.dll")]
private static extern void ReadTwoBlocks(IntPtr pathConfig, 
                IntPtr datablock1, IntPtr datablock2, int timeout, ref bool ret);

and when you use it like this:

string pathConfig = "..\program.ini";
IntPtr ptrPathConfig = IntPtr.Zero;
ptrPathConfig = Marshal.StringToHGlobalAnsi(pathConfig);
IntPtr ptrDatablock1 = IntPtr.Zero;
IntPtr ptrDatablock2 = IntPtr.Zero;
int timeout = 300;
bool ret = false;
ReadTwoBlocks(ptrPathConfig, ptrDatablock1, ptrDatablock2, timeout, ref ret);

string db1 = Marshal.PtrToStringAnsi(ptrDatablock1);
string db2 = Marshal.PtrToStringAnsi(ptrDatablock2);
情深缘浅 2024-12-21 18:14:47

封送拆收器可能因 MarshalAs(UnmanagedType.LPStr) 而窒息。您要么必须将签名更改为固定大小的 byte[] 并使用 Encoding.ASCII.GetString() 在托管代码中进行字符串转换,要么您可以使用 IntPtr 类型并使用 Marshal.AllocHGlobal 分配内存/FreeHGlobal 并处理代码中的字符串转换。

我想这可能有用..

        private const int MAX_STRING = 256;

    [DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks")]
    private static extern void _ReadTwoBlocks(
       byte[] pathConfig,
       [Out] byte[] datablock1,
       [Out] byte[] datablock2,
       int TimeOut,
       ref bool result);


    public void ReadTwoBlocks(string pathConfig,
                              StringBuilder datablock1,
                              StringBuilder datablock2,
                              int TimeOut,
                              ref bool result)
    {
        var pathConfigBuff = new byte[MAX_STRING];
        var datablock1Buff = new byte[MAX_STRING];
        var datablock2Buff = new byte[MAX_STRING];

        // Convert unicode string to null terminated single byte charater string
        Array.Copy(Encoding.ASCII.GetBytes(pathConfig), pathConfigBuff, pathConfig.Length);

        // Call your native method
        _ReadTwoBlocks(pathConfigBuff, datablock1Buff, datablock2Buff, TimeOut, ref result);

        // If success, copy the datablocks to the StringBuffers
        if (result)
        {
            datablock1.Append(Encoding.ASCII.GetString(datablock1Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
            datablock2.Append(Encoding.ASCII.GetString(datablock2Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
        }
    }

The marshaler is probably choking on the MarshalAs(UnmanagedType.LPStr). You're either going to have to change the signature to a fixed size byte[] and do the string conversion in managed code using Encoding.ASCII.GetString(), or you could use an IntPtr type and allocate the memory using Marshal.AllocHGlobal/FreeHGlobal and deal with the string conversion in your code.

I think this might work..

        private const int MAX_STRING = 256;

    [DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks")]
    private static extern void _ReadTwoBlocks(
       byte[] pathConfig,
       [Out] byte[] datablock1,
       [Out] byte[] datablock2,
       int TimeOut,
       ref bool result);


    public void ReadTwoBlocks(string pathConfig,
                              StringBuilder datablock1,
                              StringBuilder datablock2,
                              int TimeOut,
                              ref bool result)
    {
        var pathConfigBuff = new byte[MAX_STRING];
        var datablock1Buff = new byte[MAX_STRING];
        var datablock2Buff = new byte[MAX_STRING];

        // Convert unicode string to null terminated single byte charater string
        Array.Copy(Encoding.ASCII.GetBytes(pathConfig), pathConfigBuff, pathConfig.Length);

        // Call your native method
        _ReadTwoBlocks(pathConfigBuff, datablock1Buff, datablock2Buff, TimeOut, ref result);

        // If success, copy the datablocks to the StringBuffers
        if (result)
        {
            datablock1.Append(Encoding.ASCII.GetString(datablock1Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
            datablock2.Append(Encoding.ASCII.GetString(datablock2Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文