locked
BadImageFormatException when importing C++ DLL in VB RRS feed

  • Question

  • Hi,

     

    I am trying to write my first DLL and am struggling to get it working correctly and am receiving a variety of errors. For my Hello World DLL I was trying to follow this page (http://support.microsoft.com/kb/106553), but as it was very old and referring to VB 6 I am now trying to use the instructions on this page: http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx but then calling it from VB instead of from a C++ application.

     

    Essentially, what I have done is to follow all of the instructions on the second link, but then instead of calling it from C++ I call it fro my VB application (I have successfully managed to call DLLs from VB in the past). When I try to call the Add function (or any others) I get a BadImageFormatException error thrown saying "An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)" but I don't know what I am doing wrong. I have tried calling an alternative C++ function that is declared as a void and takes no arguements in order to completely avoid the problem of matching the data types but I get exactly the same error.

     

    I gather that this is sometimes to do with target architectures, and have tried setting the C++ compiler to build it as both a Win32 DLL and as an x64 DLL, and each time changed the VB settings to match the outut type of the other but this doesn't seem to make any difference, and for some permutations even makes it worse with it saying that it can't find the entry point in the DLL that I'm calling.

     

    I am completely new to this and am now at a loss for what to try and what could be going wrong, so any help would be apprecitated. The VB import is as follows:

     

     Private Declare Function Add Lib "DLL_Test.dll" (ByVal a As Double, ByVal b As Double) As Double
     Private Declare Sub HelloWorld Lib "DLL_Test.dll" ()
    

    where the C++ HelloWorld function open a message box and returns nothing, and the add function adds them and returns a double. I have tried doing it with ints instead of doubles and have tried all permutations of Int16, Int32 and Int64, also with all permutations of target architecture but to no avail. I'm sure I am missing something basic but have no idea. All C++ code is as it is on the MSDN pages linked above. Any ideas?

     

     

    (Just to state the obvious, I have copied the built output from the C++ file into the debug / release directory for the VB and have confirmed that it is finding the file by changing the DLL filename in the function import statement and I get a file not found error instead)


    • Edited by merlin fl Monday, July 4, 2011 11:10 PM inserting the hyperlinks
    Monday, July 4, 2011 11:09 PM

Answers

  • Well you can't mix the architectures. If your C++ DLL is 32-bit then it can't be loaded by a 64-bit process, and vice versa. That could explain the BadImageFormatException message.

    The entry point issue is a whole different matter. Perhaps the functions are not being exported propertly. I would recommend posting your question to Visual C++ forum to make certain that you are developing the DLL properly before attempting to load it from .NET.

    http://social.msdn.microsoft.com/Forums/en/category/visualc

     


    Paul ~~~~ Microsoft MVP (Visual Basic)
    Wednesday, July 6, 2011 2:22 PM
  • OK, sorry, apologies, this problem has now been solved, the solution is over on the C++ forum as I reposted that question there having been told that would be a more appropriate place for it. Here is a link to the solution:

     

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/6eeb2917-856a-4e65-98f2-a6f2d9315b3f



    You are pretty much right Kaymaf, it's partly architecture and partly entry point naming. When the architectures don't match I was getting a BadImageFormatException, and when they did I was getting an entry point not found error. The solution is to force it to export the function names in 'C' style format, as has been posted on the other thread.

    • Marked as answer by merlin fl Thursday, July 7, 2011 11:49 AM
    Thursday, July 7, 2011 11:48 AM

All replies

  • Hi,

    If you have built the DLL in Visual Studio proceed as follows;

     

    • Go to the PROJECT menu and select ADD REFERENCE...
    • Find your DLL file and then click on OK
    • If the original application was called WindowsApplication1 you can add the following at the top of your VB.Net Form code.

     

    Imports WindowsApplication1

    'follow it with any Class name from your C++ project.

    E.G:

    Imports WindowsApplication1.SomeClass

     

    Replace SomeClass

    with your Class name from the C++ project.

     

    It should look something like this:>>

     

    Imports WindowsApplication1.SomeClass
    
    Public Class Form1
    
    End Class
    


    You can then create an object instance created from the Class in your C++ code.  :-)

    I hope this helps.  :-D

     



    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums





    • Proposed as answer by Mike Feng Wednesday, July 6, 2011 9:46 AM
    • Unproposed as answer by merlin fl Wednesday, July 6, 2011 10:38 AM
    Monday, July 4, 2011 11:23 PM
  • Hi,

     

    When I try adding a reference I get an error message that says:

     

    "A reference to 'C:\temp\DLL_Test.dll' could not be added. Please make sure that the file is accessible and that it is a valid assembly or COM component"

     

    The file is accessible (and I have tried different locations as I know that Windows 7 can be funny about giving access to things just off the C: drive root), and I imagine that it is a valid assembly as it can find the entry points when I try to access the functions without adding a reference to my project.

     

    I don't know if this will make any difference to the answer but I don't want to create any instances from this DLL, I just want to call functions from it, like I do with the DLLs in the Windows API.

     

    Also, I am wondering if this would be better posted in the C++ forum as it could equally be (probably more likely) be a problem with the way I am building my DLL in VC++.

    Wednesday, July 6, 2011 10:49 AM
  • Is your Visual Basic .NET app running under a 64-bit OS? Try setting the Platform option (Build...Configuration Manager) to x86 and see if the DLL will load. If it does then it's a 32-bit library.


    Paul ~~~~ Microsoft MVP (Visual Basic)
    Wednesday, July 6, 2011 1:43 PM
  • My OS is Windows 7 64 bit. The target for the C++ build is currently set to Win32 and the VB application target is set to x86 and it doesn't work for this setup.

     

    I have also tried the following combinations, none of which work:

     

    C++ = Win32, VB = Any CPU

    C++ = Win32, VB = x86

    C++ = Win32, VB = x64

     

    C++ = x64, VB = Any CPU

    C++ = x64, VB = x64

    C++ = x64, VB = x86

     

    I would have thought that one of these should work, but sadly not. For some of the combinations I get the error message stated above, but for some I get it saying that it cannot find an entry point in the DLL. I think that these errors are thrown when there is an architecture mismatch i.e. when C++ is set to Win32 and VB is set to x64.

    • Edited by merlin fl Wednesday, July 6, 2011 1:52 PM Extra info
    Wednesday, July 6, 2011 1:50 PM
  • Well you can't mix the architectures. If your C++ DLL is 32-bit then it can't be loaded by a 64-bit process, and vice versa. That could explain the BadImageFormatException message.

    The entry point issue is a whole different matter. Perhaps the functions are not being exported propertly. I would recommend posting your question to Visual C++ forum to make certain that you are developing the DLL properly before attempting to load it from .NET.

    http://social.msdn.microsoft.com/Forums/en/category/visualc

     


    Paul ~~~~ Microsoft MVP (Visual Basic)
    Wednesday, July 6, 2011 2:22 PM
  • Yes, I realise that some of those combinations are pointless but I just thought that I would try all of them just in case there was something that I wasn't understanding. The point is though that the ones that do match target architectures don't work either.

     

    I thought that the fact that when the target architectures mismatch yields a different error message to when they do might be some sort of clue as to what is going wrong though...

    Wednesday, July 6, 2011 3:45 PM
  • Are you try to run the native win32 dll as .net? As far as i know, BadImageFormatException always occurs when you try to access native win32 dll as .net. In your situation, that may be different. The sample code from MSDN works if you follow the steps correctly. Try to check if those functions in the library are exported by using dumpin tool from command line prompt

    C:\> dumpbin /exports "C:\MathFuncsDll.dll"

    Then part of the output should look like this below where all the export functions are listed

     1    0 0001114F ?Add@MyMathFuncs@MathFuncs@@SANNN@Z

     2    1 000110DC ?Divide@MyMathFuncs@MathFuncs@@SANNN@Z

     3    2 0001110E ?Multiply@MyMathFuncs@MathFuncs@@SANNN@Z

     4    3 00011163 ?Subtract@MyMathFuncs@MathFuncs@@SANNN@Z 

     

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Wednesday, July 6, 2011 11:24 PM
  • OK, sorry, apologies, this problem has now been solved, the solution is over on the C++ forum as I reposted that question there having been told that would be a more appropriate place for it. Here is a link to the solution:

     

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/6eeb2917-856a-4e65-98f2-a6f2d9315b3f



    You are pretty much right Kaymaf, it's partly architecture and partly entry point naming. When the architectures don't match I was getting a BadImageFormatException, and when they did I was getting an entry point not found error. The solution is to force it to export the function names in 'C' style format, as has been posted on the other thread.

    • Marked as answer by merlin fl Thursday, July 7, 2011 11:49 AM
    Thursday, July 7, 2011 11:48 AM