Assuming that EXPORT is a #define of __declspec( dllexport ), so both functions are exported...
I think that it's safer to say that they are possibly (or probably) using a different calling convention. The first declaration is not specifying one, so it will use the default value of the project (this is __cdecl for new DLL projects, for Visual Studio, but can be changed.) All DLL exports should specifically define their calling convention.
The second version is using PASCAL for the calling convention, which is now (in Win32) a #define of __stdcall (pascal and stdcall are slightly different: see
http://en.wikipedia.org/wiki/X86_calling_conventions)
extern "C"
does turn off the C++ name mangling. But (at least for Visual C++) the exported name of the second function is
_func@0
-- the number after the @ is the number of bytes for all the function's parameters rounded up to a multiple of 4 bytes.
The first one will be just
func
if (a) it uses the default (__cdecl) calling convention and is (b) built as C (or using extern "C")
If the first one is built as C++ instead, the name will be decorated. For Visual C++ 2008, I get
?func@@YAGXZ
(Note that the decoration rules are different for different compilers)
And for completeness, removing the extern "C" from the second one gives
?func@@YGGXZ
-- just a change of the A to a G, but it means that if your DLL's header does not specify the calling convention for your exported function, and the default calling convention for the client app is different to the DLL, then the linker will fail to find the right "func".