See the question and my original answer on StackOverflow

You can't return structs from functions like you do, you can simply pass the struct by reference (this is how the whole Windows API is defined BTW).

Here is how to declare the struct, don't forget to indicate the charset is Ansi:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct Cam
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string ip;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string login;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string pass;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string name;
}

Here is how to declare the method (the ref argument is like using a *):

[DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void AddCameraStruct1(ref Cam pcam);

Here is how to declare it in C/C++:

extern "C" __declspec(dllexport) void AddCameraStruct1(Cam *pcam)
{
  strcpy_s(pcam->name, "hello"); // for example
}

Here is how you would call it now:

var cam = new Cam();
cam.ip = "192.168.0.232";
cam.login = "admin";
cam.pass = "admin";
cam.name = "kekekeke";
AddCameraStruct1(ref cam);
// cam.name is now "hello"

Note you don't need to use the unsafe keyword at all in your code.