Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to keep C++ pointers in C#?

Tags:

c++

c#

pointers

I'm currently working on some C#/C++ code which makes use of invoke. In the C++ side there is a std::vector full of pointers each identified by index from the C# code, for example a function declaration would look like this:

void SetName(char* name, int idx)

But now I'm thinking, since I'm working with pointers couldn't I sent to C# the pointer address itself then in code I could do something like this:

void SetName(char*name, int ptr)
{
   ((TypeName*)ptr)->name = name;
}

Obviously that's a quick version of what I'm getting at (and probably won't compile).

Would the pointer address be guaranteed to stay constant in C++ such that I can safely store its address in C# or would this be too unstable or dangerous for some reason?

like image 754
meds Avatar asked Aug 14 '11 13:08

meds


People also ask

Is it better to use pointers in C?

Pointers save memory space. Execution time with pointers is faster because data are manipulated with the address, that is, direct access to memory location. Memory is accessed efficiently with the pointers. The pointer assigns and releases the memory as well.

How pointer is harmful in C?

Pointers are powerful because they allow you to directly access memory addresses. This same usefulness also makes them very dangerous. If you don't use your pointers correctly you can access garbage data or leave them dangling. Another product of incorrect usage is memory leaks.

Do pointers waste memory?

You really don't waste memory at all. If you passed them by value you would waste more time and more memory. The pointer itself is a memory address but what it points to is a value in memory. This also applies to something like int ** because it points to a pointer value in memory.

Do pointers take up memory in C?

Pointers take up the space needed to hold an address, which is 4 bytes on a 32-bit machine and 8 bytes on a 64-bit machine. In C++, every value is stored somewhere in memory and can therefore be identified with that address. Such addresses are called pointers.


2 Answers

In C#, you don't need to use a pointer here, you can just use a plain C# string.

[DllImport(...)]
extern void SetName(string name, int id);

This works because the default behavior of strings in p/invoke is to use MarshalAs(UnmanagedType.LPStr), which converts to a C-style char*. You can mark each argument in the C# declaration explicitly if it requires some other way of being marshalled, eg, [MarshalAs(UnmanagedType.LPWStr)], for an arg that uses a 2-byte per character string.

The only reason to use pointers is if you need to retain access to the data pointed to after you've called the function. Even then, you can use out parameters most of the time.

You can p/invoke basically anything without requiring pointers at all (and thus without requiring unsafe code, which requires privileged execution in some environments).

like image 183
Mark H Avatar answered Oct 05 '22 01:10

Mark H


Yes, no problem. Native memory allocations never move so storing the pointer in an IntPtr on the C# side is fine. You need some kind of pinvoked function that returns this pointer, then

[DllImport("something.dll", CharSet = CharSet.Ansi)]
void SetName(IntPtr vector, string name, int index);

Which intentionally lies about this C++ function:

void SetName(std::vector<std::string>* vect, const char* name, int index) {
    std::string copy = name;
    (*vect)[index] = copy;
}

Note the usage of new in the C++ code, you have to copy the string. The passed name argument points to a buffer allocated by the pinvoke marshaller and is only valid for the duration of the function body. Your original code cannot work. If you intend to return pointers to vector<> elements then be very careful. A vector re-allocates its internal array when you add elements. Such a returned pointer will then become invalid and you'll corrupt the heap when you use it later. The exact same thing happens with a C# List<> but without the risk of dangling pointers.

like image 25
Hans Passant Avatar answered Oct 05 '22 01:10

Hans Passant