Updating DLL of a C++ project in Visual Studio - c++

I have a project that uses a DLL that I have created. Everything works wonderfully, but I am now extending the library in the DLL to optimize some older functions.
What I was wondering is if I just modify the library to where only the main function body changes and nothing else can I just rebuild the DLL and replace it with the old one or is it because the function body changed I need to rebuild any projects that used this DLL.
The main reason I asked is because all of these projects have me referencing the .lib file and to be honest I am not sure what is exactly in a .lib file of a DLL project.
Any advice would be greatly appreciated.
Thanks

If you're just changing the functions to optimize them, without changing the function signatures, then you can just build your library and deploy it (replacing the old library).
However, if you need to change the function signatures then you can do one of (at least) two things:
Modify the code that's using your library to use the new function signatures.
If #1 is not an option, then consider leaving the old function and deprecating it. Applications with make use of your latest version will have to avoid using the deprecated methods.
You can read more about .lib/.dll here: http://www.screenio.com/tips/dll.htm

If you only change function bodies, and those functions are not template functions, and you compile the dll with the same compile options, as you did back then, you should be fine.
You might have to take care that both the dll and your executable use the same version of the Microsoft C++ Runtime Library. The version of it, that will be loaded, can be overriden by manifest files.

The .lib file lets you write code that uses your DLL as though it was a static library. Essentially it contains the declarations of all the functions in your DLL. It is generated whenever you build the DLL, but if you don't add (or remove, but you should never remove once you've deployed) a function, or change the signature of a function, then it won't change. You will also have a header file to tell the compiler what functions are in your DLL and this you will change by hand when you add a function or change the signature of a function.
If your only change is a bugfix (or perf improvement or whatever) to the actual code inside a function, you can get away with deploying only the updated DLL. For other changes you must deploy the lib and the DLL. If you've changed the signature of a function you'll have to deploy the new .h, change the calling code to call with the revised parameters, and then get the calling code recompiled. If you just added something you can get away with not rebuilding the calling code.

Related

Error in finding the body of a function in VC++

I am new to programming with C++. So I am trying to inspect other's code to learn. I started inspecting a new prototype which has a function named myFcn. Its comment lines describe it requires mk.h, mk.lib and mk.dll files to be compiled. The project was successfully built. But when I go over the calling line of myFcn and press F12 (go to definition), the declaration prototype of myFcn appears and hitting again F12 does not bring me the body of the myFcn. I guess the function definition is in the mk.lib or mk.dll files. How can I find the body of the function?
EDIT 1:
If I had several dll and lib files, could I recognize the file that myFcn was compiled in?
It seems that the function you are trying to use is compiled in the library which you use.
The purpose of this system is to let people use your functions without the need for them to edit them or understand their source code. This means that the author of the library has written the function, and compiled it into a library (.dll, .lib and .h).
By including the .h file in your project, and linking the .lib at compilation and the .dll at runtime, you can use this function without the need to ever see more than the header file.
If you wish to understand the code of this function, go to their website, and see if they provide the full source code.
Edit based on edit of question: As far as I know there is no direct way to see which header file links to which library. It is possible to view which functions are in a certain library. On Linux this is the 'nm' command for .a files (gcc libraries). For Windows some methods are described here: How to view DLL functions?.
The function body is likely to be compiled, if then you can't see the source code of it.

Need help building a DLL for JNI call. Unresolved external references. Borland Compiler

I need to build a DLL that can then be loaded with JNI from a java program. I was able to do this last year and it worked fine. I'm trying to recompile my same .cpp file now though that I make the dll with and it is failing because of an included dll dependency that gets brought in.
I have a c++ program that calls about 5 functions from some existing C++ code here. These functions are part of a huge codebase that are normally all linked together to build a set of 5 dlls.
I use dependency walker to view my dll and last year it compiled with just 2 dependent system dlls being put in my dll. Today I'm trying to recompile the same dll, but it brings in a 3rd dll file if I link with the .lib file from our existing codebase that contains the functions I use.
Basically I know my dll will work fine with JNI if I can avoid that 3rd dll showing up in my program. The problem is I don't know how to reference the functions I need in my code from our existing code base without linking to the lib file.
I can get this to work with standard c++ files and methods. This problem only happens when I reference this preexisting code from our huge codebase.
If I do not link my .obj file with a .lib file from our code I get unresolved reference messages from my Borland 5.5 compiler I have to use.
The overall issue is that my dll file works fine when I call it from a c++ exe file, but Java cannot handle something in it. Also, if I compile my code into a .so file in unix instead of a windows dll, Java JNI works fine and can load it. I know the problem is related to how Windows uses dlls, and I know if this 3rd dll doesn't load as part of my dll it will also work. I just have no idea what I did last year to build my dll without this 3rd one showing as a dependency.
If I comment out the functions from our existing code it compiles fine and loads because the 3rd dll dependency doesn't get put in my dll.
More Details
I had a message about missing _strcopy, so I linked in the cw32mti.lib file and that went away, but then that cw32mti.dll shows up in my dll file. How do I prevent the missing reference message for something like that and prevent it from putting the dll in my dll?
My link command looks like this.
ilink32 mydll.obj, mydll.dll,,cw32mti
The only way I get the other missing references to work is adding the other dll to my link command like:
ilink32 mydll.obj, mydll.dll,,cw32mti.lib other.lib
Where other.dll contains functions I call from mydll.dll such as calculate(int a, int b), so my code has a link it in like calculate(num1, num2); The problem is when I use the lib that contains the calculate method, it also brings in other dlls linked to the other.dll that I do not want to load. I need to be able to call calculate(num1, num2) without adding other.dll to mydll.dll. This worked before without dynamically calling calculate and using the getprocaddress type of coding.
Update - I eventually had to give up on getting the windows dll to work with the smartheap memory manager. Since this code was deployed in unix, I was able to just build the .so files and get those to work with JNI. For the Windows dll compile, I put some conditional compiler statements around the JNI code that was causing the smartheap dll to be loaded, so then when it compiles in windows it does not use that code. Instead I just had it print out a statement saying it was not executing in windows.
We also ran into issues later with getting our 64 bit JBoss server to run and load these 32 bit .so files. I ended up running a parallel JBoss server next to the 64bit one and called the methods that referenced the 32 bit library on the 32 bit instance of JBoss.
It may evolve into more later, but for now this task is working for us after months of trying many different things. I appreciate all of the help and input here.
If you can get your hands on the application DLL built from last year, use TDUMP to see what the module dependencies are. (You might have to analyze all the DLLs to get a good picture.) Then endeavor to reproduce that in the new DLL, probably by adjusting the linker's configuration .DEF file.
Without any code or .DEF file shown in your question, it is very difficult to be more specific.

How to call a unmanaged C++ exe from managed c++ exe

Please tell me how to call a unmanaged c++ exe functions from managed c++ exe or dll? help with code example would be more useful.
Thank you
You need to link against the library that contains the function you want to call, include a header that defines the function and then just call it.
Without a more specific question you're not going to get much more than that.
I think you should have a look at P/Invoke. Using this tech you could call any unmanged function exported in a DLL or EXE from a managed function.
For example:
http://www.codeproject.com/KB/cs/essentialpinvoke.aspx
The managed/unmanaged is a red herring. When you have some code you want to call, it should be in a lib, a DLL, or a COM exe. A regular double-click-it-to-run-it exe that doesn't implement any COM interfaces doesn't expose any of its code to outside callers. If you just want to run it, you can use Process.Start to launch the whole exe. Otherwise you're going to need to re-architect a bit (this will involve having the source code to the other exe.) Generally I pull most of the functionality into a lib or dll, have the original exe call into that library to get its work done, and have the new exe also call into the same library.
Since you're in C++/CLI, do not go COM Interop or P/Invoke. IJW is way easier (it just works, right?) Include the header, link to the lib. Done! But as you now see, getting the lib can be the big first step.

do you have to get rid of the WinMain to turn a project into a lib

say I built an application called App1 with a lot of classes in a single project. And I decide that I want to build another project called App2 and I want to use those same classes so I decide to turn App1 into a lib file. Must I remove the WinMain function to do so or can I leave it and the compiler will ignore the winMain in the lib file. ??
Particularly in Visual Studio your static library won't cause troubles in any case. Even though you can add your WinMain (or console main) to a static library, your only chance to use it in your second project is by explicitly seeting Linker-System-Subsystem to appropriate type.
In this case if you match the routine (WinMain for windows subsystem and main for console), then you can actually compile your second project without defining the main routine in it and main would be linked from your library.
Still, in this situation, if you declare that main and ALSO link your library, your local main will have priority and will be called, so that main in library will be ignored.
So, there is actually no difference for you if you export you function to the library or not, you can leave it and it won't be used unless you make what I've pointed to earlier.
It just doesn't make any sense to do this. Spin the classes off in their own library project that builds a .lib, have both apps use the library.

Why can't a "procedure entry point could not be located in dll" when I definitely put it in?

I have a really vague problem, but I hope someone can help with it. I was modifying a C++ project and yesterday it was still working, but today it's not. I'm pretty sure I didn't change anything, but to be completely sure I checked the project out from SVN again and I even reverted to a previous system restore point (because this is a work computer, it sometimes secretly installs updates etc.). After succesfully compiling it, the program can start up, but after I interact with it, I get this error:
The procedure entry point ?methodName#className##UAEXXZ could not be located in the dynamic link library libName.dll.
I've searched the internet, but most people's problems seem to be caused by an older version of the DLL being used. I searched my computer and there is no older version. If I delete the correct version, the application doesn't start. If I then recompile the project, the DLL is created again, so I'm both pretty sure that the application is using the correct DLL and that the compilation is creating it. If I introduce syntax errors into the method that the error refers to, the project refuses to compile, so I guess this means that it is also compiling the files that contain the method.
Basically I don't know anything about DLL's, linking, etc. so I would greatly appreciate it if anybody has an idea as to why the functions that are very clearly defined in the project are all of a sudden not making it into the DLL anymore. I know this is vague and if any more information is required I will gladly provide it. Thanks!
Update: I have tried the given suggestions, but I'm still stuck. __declspec(dllexport) is apparently not used in the entire project. Opening the DLL with Dependency Walker shows me an empty top right section and the section below it lists the function from the error message. If I check Undecorate C++ Functions it looks fine, but if I don't I get the weird question marks and #s from the error message and there appears to be a difference at the end:
?methodName#className##UAEXXZ
?methodName#className##UAEXH#Z
Perhaps this is the problem, but I have no idea what it means, what may have caused this and what I can do about it.
Are you actually using __declspec(dllexport)? My guess is no -- without that declaration, that function will not be exported by the DLL (or in other words, programs loading that DLL will not have access to functions without that declaration).
Also, try using Dependency Walker to see exactly which functions your DLL has made available.
The fact that __declspec(dllexport) isn't used in function declarations is okay -- most of the time, it will only be used once in a single header file, like
#ifdef MAKING_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API
#endif
So that if you have #define MAKING_DLL before that section, all functions that are declared like FOO_API int BakeACake() will be exported based on whether MAKING_DLL was defined. It's possible that the project was expecting MAKING_DLL (or its equivalent) to be defined on the command line, depending on the project type built (something like /DMAKING_DLL; or you might even need to define FOO_API yourself like /DFOO_API=__declspec(dllexport).
The empty top right section in Dependency Walker just means your program isn't linking against the DLL's corresponding .lib file. That's okay, it just means you are using LoadLibrary or LoadLibraryEx to access functions in the DLL.
Another fairly likely scenario (based on the fact that the mangled names are different) is that the program was built using a different version of Visual Studio than 2008, which you used to build the DLL. Unlike plain C, there's no standard binary interface for C++, which means that you have to use the same compiler to build the program and the DLL when you are using C++ classes in the DLL. If you can, try rebuilding the program in VS2008, or try rebuilding the DLL in the same version of VS as the program was built.
Download dependency walker and open your dll using this tool. It will show a list of exported functions from your dll. Check whether the above said method is part of the expected functions. If it's not, then it means you accidentally removed __declspec(dllexport) for one of the classes in that dll.
I feel a bit stupid, but I found the answer. The application (exe) I was using apparently loaded a second, different dll which had a dependency on the one mentioned in my original post. This second dll was still expecting the old functions and also needed to be recompiled against the updated dll.
Many thanks to the people who tried to help me here!
Using information of the posts above I found simple general solution. All you need to do is open programs executable with dependency walker, look for the missing functions, look what dll's are using it, find the project which builds that dll and rebuild it.