Is this P/Invoke code standard? I have two projects, a native C++ DLL (pinvokelib.dll), and a C# console application (pinvoketest.exe) which calls the DLL. I'm curious if the way I do P/Invoke is considered best practice.

Here is my C++ code:

extern "C" __declspec(dllexport) int test(int val);

int test(int val)
{
    return val * 2;
}


And my C#:

using System;
using System.Runtime.InteropServices;

namespace pinvoketest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(test(42));
            Console.ReadLine();
        }

        [DllImport("pinvokelib.dll", CallingConvention=CallingConvention.Cdecl)]
        static extern int test(int val);
    }
}


I'm using Visual Studio 2012 Express to compile both.

Is there any way that the code can be improved? Is there something redundant? I'm especially unsure about the first line of the C++ code, since I don't understand everything about it very well.
If you don't call your function recursively from C, you don't need to have separate defition and declaration:

extern "C" __declspec(dllexport) int test(int val)
{
    return val * 2;
}


And if you have more than one function you want to export, you can use extern "C" as a block:

extern "C"
{
    __declspec(dllexport) int test(int val)
    {
        return val * 2;
    }

    // more functions here
}


As to what does it all mean:


extern "C" tells the compiler not to mangle the name of the function; this is normally necessary to support C++ function overloading
__declspec(dllexport) means that this function will be exported from the DLL, so that you can use it from outside this library