how to get the unsigned char * value in .net?

mc 3,746 Reputation points
2023-10-13T06:30:37.9966667+00:00

a function in c++ dll will return a byte[] (unsigned char *)

how to receive it in c#?

public static extern IntPtr ReadData(int id);

you may say I can use Marshal.Copy,

but there will be error of ExecutionEngineException

the byte is 10mb and I will frequently read it.

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,468 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,689 questions
Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
732 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 44,186 Reputation points Microsoft Vendor
    2023-10-13T12:35:45.2233333+00:00

    Hi,@mc. Welcome Microsoft Q&A.

    The equivalent of unsigned char in C# is byte.

    byte getValue(string s)
    {
    
    }
    

    Second option: if you use unsigned char as a character storage, you should use char:

    char getValue(string s)
    {
    
    }
    
    
    

    C++ treats characters and 8-byte values equally. You could check from the context, whether the unsigned char is a character or a number. From string being passed as a parameter, one can guess, that the function processes characters so mostly probably you want a char C# type.

    Here are examples you could try to refer to.

    Method1:

    Dlltest.h

    
    #define DLL_EXPORT extern "C" __declspec(dllexport)
    DLL_EXPORT char* func_getRbtData();
    DLL_EXPORT void func_freeRbtData(char*);
    class Attempt {
    	int x;
    public:
    	Attempt(int x);
    	int adding(int y);
    };
    extern "C" _declspec(dllexport) void* Create(int x) {
    	return (void*) new Attempt(x);
    }
    extern "C" _declspec(dllexport) int AttemptAdd(Attempt * a, int y) {
    	return a->adding(y);
    }
    
    

    Dlltest.cpp

    char* func_getRbtData()
    {
        const char* _getRbtData = "1.0;23.0;55.0;91.0;594.0;";
        int len = strlen(_getRbtData);
        char *getRbtData = new char[len+1];
       
        memcpy(getRbtData, _getRbtData, len+1);
        return getRbtData;
    }
    
    void func_freeRbtData(char *p)
    {
        delete[] p;
      
    }
    Attempt::Attempt(int x)
    {
    	this->x = x;
    }
    int Attempt::adding(int y)
    {
        return this->x + y;
    }
    
    

    UITest.xaml.cs

    
    [DllImport("DllTest.dll", EntryPoint = "func_getRbtData", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr func_getRbtData();
    
    [DllImport("DllTest.dll", EntryPoint = "func_freeRbtData", CallingConvention = CallingConvention.Cdecl)]
    public static extern void func_freeRbtData(IntPtr p);
    
     [DllImport("DllTest.dll")]
            public static extern IntPtr Create(int x);
    
            [DllImport("DllTest.dll")]
            public static extern int AttemptAdd(IntPtr a, int y);
    
    string[] words;
    private void btn_test_Click(object sender, RoutedEventArgs e)
    {
        IntPtr a = Create(5);
        AttemptAdd(a, 110);
        MessageBox.Show(Marshal.ReadInt32(a).ToString());
    
        IntPtr intptr = func_getRbtData();
        string str = Marshal.PtrToStringAnsi(intptr);
        func_freeRbtData(intptr);
        // alternatively:
        // Marshal.FreeHGlobal(intptr);
        words = str.Split(';');
        lb_content.Content = words[1];
    }
    
    
    

    Method 2:

    
      [DllImport("YourCppLibrary.dll")]
            public static extern IntPtr ReadData(int id);
    
            public static byte[] ReadDataAndConvert(int id, int dataSize)
            {
                IntPtr dataPtr = ReadData(id);
                if (dataPtr == IntPtr.Zero)
                {
                    // Handle the case where the function returns null (if needed)
                    return null;
                }
    
                byte[] result = new byte[dataSize];
                Marshal.Copy(dataPtr, result, 0, dataSize);
    
                return result;
            }
    

    If you still have questions, please feel free to let me know. The problem will be better solved if more details are described (steps, error messages, and code to reproduce the problem).


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful