none
Compiling c code using CLR and varargs lead to BadImageFormatException RRS feed

  • Question

  • Hi.

    We've got some inhouse libraries written in C, and the Debug library has among other things a logging function that uses varargs. And it seems as if it uses one or more of va_arg, va_end, or va_start, I get a BadImageFormatException when I load the assembly in C#.

    I load it this way:
    Assembly assembly = Assembly.Load( "AdfDotNetDll_R" );

    Has anyone encountered this problem? I've searched (of course) a lot but haven't found anything, except for this comment....

    "Functions that take a variable number of arguments (varargs) will be generated as native functions. Any managed data types in the variable argument position will be marshaled to native types."

    .... and this page describing a possible issue: http://msdn.microsoft.com/en-us/library/kb57fad8.aspx
    But the problem on that page doesn't seem to indicate that it should throw an exception upon loading, only that it will throw an exception when the code actually executes.

    Any help is greatly appreciated!

    Thursday, August 14, 2008 4:06 PM

Answers

  • Check out http://msdn.microsoft.com/en-us/library/aa712815.aspx.

    The following cases prevent the compiler from generating managed code.
    • Functions containing __asm blocks.
    • Functions whose parameter lists use varargs/stdargs.
    • Compiler-generated thunks or helper functions. Native thunks are generated for any function call through a function pointer, including virtual function calls.
    • Functions that call setjmp or longjmp.
    • Functions that use certain intrinsic routines to directly manipulate machine resources. For example, the use of __enable and __disable, _ReturnAddress and _AddressOfReturnAddress, or multimedia intrinsics will all result in native code.
    • Functions that follow the #pragma unmanaged directive. (Note that the inverse, #pragma managed, is also supported.)
    • A function that contains references to aligned types, that is, types declared using __declspec(align(...)).

    Michael Fischer

    • Marked as answer by Zhi-Xin Ye Tuesday, August 19, 2008 12:02 PM
    Friday, August 15, 2008 2:29 PM

All replies

  • Native DLLs such as those written in C# are not loaded using Assembly.Load.  Instead you should use DLLImportAttribute to import the libary.  If you wanted more control over it you could use the Win32 LoadLibrary call (which would use a DLLImport as well but that file has a much greater chance to be on any system you try to run your application on.

    Michael Fischer
    Thursday, August 14, 2008 11:48 PM
  • Yes, varargs are not compatible with managed code, the C++/CLI compiler will automatically switch to generating unmanaged code.  That will cause a BadImageFormatException when you run this code on a 64-bit operating system.  Not sure if this explanation is a good match for your scenario.
    Hans Passant.
    Friday, August 15, 2008 2:56 AM
    Moderator
  • Michael, I forgot to mention that I'm compiling it using /CLR, so the idea was that it wouldn't be a native dll. But I guess it's like nobugz says, that when you use varargs, that's what it gets compiled to.

    I am however running on 32bit windows. Another help source told me to change to try and run in X86 instead of Any CPU, but I can't access the configuration manager in this solution. I'm not sure why, it works fine in another one. I'm using Visual Studio 2005 Express edition.

    So I guess the only options are to either not use varargs, or to use it as a native dll. This may seem like a stupid question, but can native dlls export only functions or can they export classes/struct definitions as well?

    Thanks for the help!
    Friday, August 15, 2008 8:38 AM
  • Yes you can export classes and their methods from a native C++ DLL, but you can't consume those classes from C#.
    Mattias, C# MVP
    Friday, August 15, 2008 11:15 AM
    Moderator
  • Check out http://msdn.microsoft.com/en-us/library/aa712815.aspx.

    The following cases prevent the compiler from generating managed code.
    • Functions containing __asm blocks.
    • Functions whose parameter lists use varargs/stdargs.
    • Compiler-generated thunks or helper functions. Native thunks are generated for any function call through a function pointer, including virtual function calls.
    • Functions that call setjmp or longjmp.
    • Functions that use certain intrinsic routines to directly manipulate machine resources. For example, the use of __enable and __disable, _ReturnAddress and _AddressOfReturnAddress, or multimedia intrinsics will all result in native code.
    • Functions that follow the #pragma unmanaged directive. (Note that the inverse, #pragma managed, is also supported.)
    • A function that contains references to aligned types, that is, types declared using __declspec(align(...)).

    Michael Fischer

    • Marked as answer by Zhi-Xin Ye Tuesday, August 19, 2008 12:02 PM
    Friday, August 15, 2008 2:29 PM