Link to home
Start Free TrialLog in
Avatar of dav667
dav667

asked on

Binary Compatiblity - Packaging and referencing of Dlls

Hi,
I have a problem with a vb app that I'm working on. The app is a 2 tier thing, using COM. The problem is simply that I can't get it to work, and I think it lies with the Binary Compatibility issue. I've looked into this on various sites, but so far have had no luck. Currently the dlls are set to ActiveX dlls (in project properties) and have binary compatibility set to the old version of the app's dlls (which work). The 'back end' tier is set to an ActiveX exe project, and currently has compatibility set to project compatibilty (to the previous version of the app). I think it might need to be set to Binary compat but when this is set it doesn't compile and gives the error

"The Binary compatibility DLL or EXE contains a parameter type or return type whose definition can not be found"
If anybody knows what this error means that would be great!

The front tier is compiled as a Standard EXE (and so has no compatibility options - is this right??). I'm not sure how it works with regards to the references to the dll (in both the tiers) when I package it. Where does VB store the refernced dll info when it packages it?

Any help in providing info on how this should work would be much appreciated, as I've spent far too long trying to solve this problem!!

Thanks
Avatar of muzzy2003
muzzy2003

Your old ActiveX EXE against which you are setting binary compatibility defines a method parameter or return value with a type that was defined in the old EXE (an enum, or perhaps a class instance), and that enum or class instance has changed in the current version. Here is what I'd do:

Step 1. Break binary compatibility on the ActiveX EXE. Set compatibility to none, recomplile, then reset it to binary compatibility to the old version. Does this work?

If so, step 2. Fix the references in your ActiveX DLLs to the ActiveX EXE (go in to project references, remove the broken references, get back out, go back in again, add the references). Recompile the ActiveX DLLs. Does this work? If not, then follow the steps in Step 1 for the ActiveX DLLs as well.

Finally, step 3, fix the references in your Standard EXE to the ActiveX DLLs as described in Step 2.

When you break compatibility, you change the CLSID used to reference your DLL. This is compiled into your calling EXE, so if you break compatibility, it no longer can locate the DLL. In a multi-tier application like this, project compatibility can create more problems than it solves - my advice is to avoid.
Avatar of dav667

ASKER

Thanks for the quick reply!!
I tried what you suggested in Step 1 but with no luck. If I break the compatibility it compiles fine, but then when I set it to binary compatible to the original version it doesn't work (giving the same error as before).
With what you say about the error, does this mean that the app has changed too much and it is literally impossible to have binary compatibility to the old version? - I'm sure I've previously done this without an error?
The issue is that the front end code has already been deployed to all of the end users, and I really need to avoid having to repackage and re-deploy this as this would cause extensive delay to the project (I'm working for a large client, with strict rules, and procedures that I need to follow before doing this unfortunately).
I presume I'm right in thinking that the front end bit is right being set to 'standard EXE' and thus having no binary compatibility settings?
I understand that by maintaining BC, the same CLass IDs are used in the registry as in previous versions, but how does the client bit know which class IDs to look for anyway (being that nothing in the client bit refers to BC).
The issue is further complicated by the fact that both tiers use the same DLL - should the DLL be exactly identical, or is it only the backend copy of the DLL that needs BC enabled?


Thanks again!
No, in step 1 you set binary compatibility to the one you have just compiled (to try to prevent future problems) - NOT to the original one. With this error, you cannot keep binary compatibility with older versions.

By breaking binary compatibility in your ActiveX EXE like this, there is not necessarily any need to break it in the ActiveX DLLs (unless the Standard EXE also has a reference to the ActiveX EXE which I don't think it should from your description). You should be able to break compatibility in the ActiveX EXE (step 1), fix the references in the ActiveX DLLs (step 2a) and leave the Standard EXE as it is if that is your aim.
Avatar of dav667

ASKER

Ah I see...
No, the standard EXE doesn't actually have a reference to the ActiveX EXE, but just to the dll. Obviously it does however use the ACtiveX exe (it looks up in the registry for the name of the server, and exe filename that it should be looking for).

So from what you say, I can actually break compatibility in the activeX EXE and as long as I keep it in the activeX DLLs I can still use the same client without redploying it?
What confuses me about this though is, how does the standard EXE (ie the client) know which classIDs to look for (on the activeX EXE on the server), as the way I understood it, when you break compatibility you have to recompile the client as well, so that it still knows where to find the classes and to avoid the error 429 thing (activeX could not create Object).
Does this mean that the activeX DLLs somehow store the classIDs?

Sorry to ask so many questions, its just I need to be really sure I understand whats going on because I don't want to muck it up and have to redeploy the client if at all possible.

Thanks!
Yes, exactly right.

The client for the ActiveX EXE is the ActiveX DLL (or DLLs). The Standard EXE is only a client for the ActiveX DLL(s). The ActiveX DLL(s) store the CLSID of the ActiveX EXE, the Standard EXE the CLSID(s) of the ActiveX DLL(s). So, you can break compatibility in the ActiveX EXE, recompile the ActiveX DLL(s) against it (KEEPING binary compatibility) and not have to change anything in the Standard EXE.
I understand that by maintaining BC, the same CLass IDs are used in the registry as in previous versions, but how does the client bit know which class IDs to look for anyway (being that nothing in the client bit refers to BC).
It does it through the registry.

Using an example object classname of MyLibrary.MyClass:

 When you either early bind (Dim MyObject As MyLibraryMyClass) or late bind (Dim MyObject As Object / Set MyObject = CreateObject("MyLibrary.MyClass") your object, vb reads HKEY_CLASSES_ROOT\MyLibrary.MyClass\Clsid. This returns the CLSID. If you have early-bound, the CLSID is referenced in the executable - not the class name.

If - as it appears - you have changed the public interface of the dll (not just added to it), you will not be able to maintain binary compatibility. So, unregister your existing DLL, recompile your new one (without BC) save your new dll somewhere and set it as your new BC dll.

Recompile front and back-end apps against your new dll.

Unregister your old dll on all machines that it it is on.

Redistribute Apps and dll. Registering new dll on all machines.

Next time be more careful with the public interfaces ;-)

Avatar of dav667

ASKER

Thanks for your replies!

fds fatboy:
So from what you are saying, there is no other way round this then to recompile and redistribute both tiers? (I was coming to this conclusion, but desperately trying to avoid it!).

It seems like what muzzy2003 is saying contradicts the comments from fds fatboy, is there anyone out there that can verify either opinion?

Thanks again!
No, I am right, and I think perhaps fds_fatboy has misunderstood your situation slightly. As the only project you have broken BC in is the ActiveX EXE, then you only need to recompile the projects that reference this, the ActiveX DLLs. You can do this without breaking BC in them AS LONG AS they don't expose anything from the ActiveX EXE in their own interfaces. If you can manage this, then you won't even need to recompile the Standard EXE.
Or possibly I've misunderstood your situation slightly ...

Sorry, last post sounded a bit arrogant unintentionally.
Avatar of dav667

ASKER

Thanks again muzzy2003,

Looking on one of the users machines, I see that for each class in the activeX EXE, there is a reference to the tlb file.
What exactly is a tlb file and where does that come into play?

Thanks
ASKER CERTIFIED SOLUTION
Avatar of muzzy2003
muzzy2003

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dav667

ASKER

Thanks very much for your help so far muzzy2003.

The plot thickens however...
My original error of "The Binary compatibility DLL or EXE contains a parameter type or return type whose definition can not be found"
is only produced (in the ActiveX EXE) when the dll I have referenced is the one for the latest version. If I reference the dll made in the previous version, no error is produced. - any ideas why this is?
The activeX EXE has BC enabled to the its previous version (of the activeX EXE) when this error is produced.

I'm new to this whole EE game - is it best if I start a new post with this one (naturally I will deal out the points first)

Thanks
You may want to fix

"The Binary compatibility DLL or EXE contains a parameter type or return type whose definition can not be found"


problem first


https://www.experts-exchange.com/questions/20856300/The-Binary-compatibility-DLL-or-EXE-contain-a-parameter-type-or-return-type-whose-definition-can-not-be-found.html
Sorry - the ActiveX EXE references the DLL? I thought it was the other way around?
Avatar of dav667

ASKER

muzzy2003 - yeah, both the activeX EXE (on the server) and the standard EXE (on the client) reference the activeX DLL.
So what do the ActiveX DLLs reference? I thought they referenced the ActiveX EXE?
Avatar of dav667

ASKER

Sorry, I should have probably made it more clear..
The activeX DLLs don't reference anything (well apart from the usual stuff)
Avatar of dav667

ASKER

Hi all,
I have unfortunately decided to go down the re-compile and re-deploy all parts of the app option.
Thanks for all the help...
I well may have misunderstood. I'm trying to read this stuff and do my job at the same time. If you have broken binary compatibility you need to recompile and redistribute as far down the chain until the public interface is not affected. Does that make sense? Possibly.

:-)
Avatar of dav667

ASKER

No worries fds fatboy, your efforts were appreciated!
I think it is best in this case to break compatibility in this case and start from a 'clean slate'. Unfortunately I wasn't responsible for the actual development of this app, just brought in when the release went pear shaped! But at least I'll know to be wary of Binary Compatibility issues in the future!
fds - no, I think you were closer to the mark than I was in the end. I'm in the same boat, and rattling off some of these posts far too fast! :)

dav667 - I'd give at least some of the points to fds_fatboy if I were you.
Avatar of dav667

ASKER

As you've probably realised - I'm new to this game.
How do I split points, as I was planning to give some to fds as well...
Dunno - fds? Any ideas?
Don't worry, I'll be survive without them ;-) And anyway I don't know how to. An expert - that's what you need.