谁使用DllImport移动了我的byte []? [英] Who Moved My byte[] using DllImport?

查看:75
本文介绍了谁使用DllImport移动了我的byte []?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在VC ++ 6.0中写了一个名为LibTest.dll的测试用例(类似于strcpy)



LibTest.h如下所示:

I wrote some testcase named LibTest.dll (act like strcpy) in VC++ 6.0

LibTest.h shown as below:

///////////////////////////////////////////////////////////////////////////////
#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT void LibTestInit();
DLLEXPORT void LibTestStrCpy(char *in, char *out);
DLLEXPORT void LibTestCleanup();



LibTest.cpp如下所示:


LibTest.cpp shown as below:

///////////////////////////////////////////////////////////////////////////////
#include "LibTest.h"

#include <stdio.h>

namespace CCTEC 
{
    class Test 
    {
    public:
        Test() {}
        ~Test() {}

    public:
        void strcpy(char *in, char *out) 
        {
            while (*out++ = *in++);
        }
    };
};

static CCTEC::Test *m_Test = NULL;

DLLEXPORT void LibTestInit() 
{
    m_Test = new CCTEC::Test(); 
}

DLLEXPORT void LibTestCleanup() 
{
    if (m_Test) delete m_Test; m_Test = NULL; 
}

DLLEXPORT void LibTestStrCpy(char *in, char *out) 
{
    if (m_Test) m_Test->strcpy(in, out);
}</stdio.h>





然后使用DllImport调用非托管函数(例如LibTestInit)

在DLL中实现(LibTest.dll)



LibTest.cs(源代码的一部分)如下所示:





Then using DllImport to call unmanaged functions (such as LibTestInit )
that are implemented in a DLL (LibTest.dll)

LibTest.cs (part of the source code) shown as below:

using System.Runtime.InteropServices;

public class LibTest
{
    #region DLL Import
    [DllImport("LibTest")]
    private static extern void LibTestInit();

    [DllImport("LibTest")]
    private static extern void LibTestCleanup();

    [DllImport("LibTest")]
    private static extern void LibTestStrCpy(byte[] inStr, byte[] outStr);
    #endregion

    public LibTest() 
    {
        LibTestInit();
    }

    public void Dispose() 
    {
        LibTestCleanup();
    }

    public void StrCpy(byte[] inStr, byte[] outStr) 
    {
        LibTestStrCpy(inStr, outStr);
    }
}





和Form1.cs(带有TextBox控件来测试输出)如下所示:





And Form1.cs (with a TextBox control to test the output) shown as below:

m_LibTest1 = new LibTest();
byte[] outStr1 = new byte[1024];
m_LibTest1.StrCpy(System.Text.Encoding.Default.GetBytes("Hello World"), outStr1);
m_LibTest1.Dispose();
m_LibTest1 = null;
textBox.Text += System.Text.Encoding.Default.GetString(outStr1);
MessageBox.Show(System.Text.Encoding.Default.GetString(outStr1));

m_LibTest2 = new LibTest();
byte[] outStr2 = new byte[1024];
m_LibTest2.StrCpy(System.Text.Encoding.Default.GetBytes("Hello Linux"), outStr2);
m_LibTest2.Dispose();
m_LibTest2 = null;
// FIXME: There is no Hello Linux shown in the textBox.Text
textBox.Text += System.Text.Encoding.Default.GetString(outStr2);
// XXX: But shown by MessageBox
MessageBox.Show(System.Text.Encoding.Default.GetString(outStr2));





预期输出:Hello WorldHello Linux

实际输出:Hello World



所以谁动了我的Hello Linux byte []?

请有人抓住移动我的byte []的小偷,非常感谢!



Expected output: Hello WorldHello Linux
Actual output: Hello World

So Who Moved My "Hello Linux" byte[] ?
Please someone catched the thief who moved my byte[], thanks a lot!

推荐答案

你可以在你的C#中使用MarshalAs dllimport函数。

我认为这只是一个与编组有关的问题。
You can use "MarshalAs" in your C# dllimport function.
I think it's a problem related to marshaling only.


问题看起来很简单,但我需要一些时间来调试它。现在,我在这里只看到一个问题:默认情况下,类型 * char 被列为 System.String 。 Seriosly!请参阅标准编组。



-SA
The problem looks trivial, but I would need some time to debug it. Right now, I see only one problem here: the type *char by default is marchalled as System.String. Seriosly! See standard marshalling.

—SA


来自C#代码:

- 如果要传递字符串作为输入参数,请使用 string type。

- 如果要传递字符串并修改其字符串内容,然后使用 StringBuilder 类型。



From C# code:
- If you want to pass a string as input parameter, use string type.
- If you want to pass a string and modify its content, then use StringBuilder type.

public class LibTest
{
    //and don't forget to tell how big is your buffer
    [DllImport("LibTest")]
    private static extern void LibTestStrCpy(
       //this in an input string. So pass it as a string
       string inStr,
       //this is an output string. So pass it as StringBuilder
       StringBuilder outStr,
       //this is the size of the output buffer (the capacity of the StringBuilder)
       int maxLength);

    public void Test()
    {
        string inputString = "testing...";
        //create a StringBuilder with enough storage
        StringBuilder str = new StringBuilder(100);
        //call the function
        LibTestStrCpy(inStr, str, str.Capacity);
        //gets the output string
        string outputString = str.ToString();
        ...
    }    
}





修改你的C ++代码:



And modify your C++ code like that:

class Test
{
...
    void strcpy(const char *in, char *out, int sizeOfOut)
    {
        for (int i = 0; i < sizeOfOut - 1 && *in != '\0'; i++)
            *out++ = *in++;
        *out = '\0';
    }
...
};

DLLEXPORT void LibTestStrCpy(const char *in, char *out, int sizeOfOut)
{
    if (m_Test)
        m_Test->strcpy(in, out, sizeOfOut);
}


这篇关于谁使用DllImport移动了我的byte []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆