I have the need to use a ddl from one app inside another app. Both apps use MSSQL driver.
So I have App A(dctA) ->dll 1,2,3->data dll A
App B(dctB) ->dll 4,5,6->data dll B
I would like to call for example a procedure inside dll 4 from App A frame.
The App A referencing dll 4 compiles but when it starts it keeps asking me for sql login, even if the variable is set, but then after if I insert manually the sql login parameters the application crashes in clarun, clamssql
Is it possible to achieve what I want or the only way is to have one dictionary and one data dll?
I assume you are using ABC? I suspect you are running into the need for each ABC Data (DCT) DLL to be initialized, actually all the ABC DLLs need to run the ABC DLL Init code.
On GitHub I created the below example of Legacy and ABC coexisting. The SchoolBoth folder would be the project of interest here.
What this required was 2 Data DLLs one Legacy and one ABC. The Legacy APP was primary and it provided the frame. I needed the Legacy frame to run the ABC DLL Inits. I did this by making the Hand Coded ABC Init DLL that gets called by the frame that has this code:
Abc_Init_Kill PROCEDURE(BYTE KillMe=0) CODE Message('Abc_Init_Kill v2 KillMe=' & KillMe) IF ~KillMe AND ~AbcHasBeenInited THEN GlobalErrors.Init(GlobalErrorStatus) FuzzyMatcher.Init ! Initilaize the browse 'fuzzy matcher' FuzzyMatcher.SetOption(MatchOption:NoCase, 1) ! Configure case matching FuzzyMatcher.SetOption(MatchOption:WordOnly, 0) ! Configure 'word only' matching INIMgr.Init('.\AbcInitExe.INI', NVD_INI) ! Configure INIManager to use INI file DataAbc:Init(GlobalErrors, INIMgr) ! Initialise dll (ABC) ProcABC:Init(GlobalErrors, INIMgr) ! Initialise dll (ABC) AbcHasBeenInited=1 ELSIF KillMe AND AbcHasBeenInited AbcHasBeenInited=0 INIMgr.Update DataAbc:Kill() ! Kill dll (ABC) ProcABC:Kill() ! Kill dll (ABC) INIMgr.Kill ! Destroy INI manager FuzzyMatcher.Kill ! Destroy fuzzy matcher END RETURN
I think you need to make a similar ABC Init DLL for your App B chain. I made my ABC Init DLL by making an EXE APP with just the ABC frame (AbcInitExe.cwproj) that linked in the DLLs, then copied the generated code into my hand code project AbcIniDLL.cwproj
Thanks for detailed answer.
Yes I was thinking about dct init procedures, but what made me think it is impossible is that after I inserted the sql login the app crashed. It might be something specific to the mssql driver. Which driver you have used in legacy and abc data dlls?
The thing is that the abc init procedures are called really, since both apps are abc and so for what concerns the App A the dll 4 is just another dll, and it does as for the others.
How is your connection string declared?
Do you use a global variable declared in the DCTs and if so are the 2 global variables exactly the same?
We have 10 functional modules each with their own DCT and data DLL and we call procedures in one functional module from another functional module and it all works.
In our case we’re using the Clarion (AKA Legacy) template chain with the same SQL_GLO:Owner string declared in every DCT
I suspect you might have huge problems with the ABC Class declarations from each Dll stomping on the other. There would also be the problem of globals that exist in both, and are looked at locally to that dll.
I’m not sure you can do this.
No, I do not have compilation problems.
This is interesting.
Yes I use the same global variable but I came up with the following solution.
Create common dll that will hold just a global non threaded variable for the owner.
All other dll’s reference this.
The first app that starts sets this variable.
All the procedures, in every module, that I know will be first in thread read this variable and sets the real owner variable.
I am not sure on the following.
If data dll A and B both exposes ownerVariable X, same name, and when bulding dll 4 references data dll B and dll1 references data dll A, when starting the A app, the dll 4 will still reference ownerX from data dll B, because it was specified so when data dll 4 was compiled.
I mean, I know there is something as late linking, but I encountered this years ago in embedded developing not in windows.
Anyway this is interesting. Are you using mssql driver?
Yes we’re using the MSSQL driver as well.
It all seems magical but Clarion sorts it out somehow
We’ve had instances in the past where developers have called procedures in a DLL and specified the wrong DLL name, but Clarion even sorts that out as long as the DLL is referenced somewhere in the APP
ok, thanks, then another round if investigation is needed
One of the advantages of my datafier class that I wrote about in Clarionmag, was that you didn’t have to worry about who owns what variable. OTOH, it did require a global class. But that’s it. Then you could save/retrieve as many “global” values as you wanted, from any app, without having to compile any other app unless they have a specific need for this value for something.
Interesting concept, but I do not think it can help with my MSSQL/ two data dlls problem I think
I had something similar with one EXE that worked with 2 DLL “chains” each with its own DCT Data DLL. I also ended up making a common data DLL used by both for some exported data variables that had to be shared by both.
I did these 2 DLL chains because the changes needed for the “new system” were major, and I needed the old code to still work the same for 3 years. To make the code work both ways seemed too risky. So I copied all APPs and started building the new system.
One discovery is you CANNOT have 2 APPs with the same name even though they build different target DLL names. The APP Name is used to name Resources in the DLL like Windows are a resource in DABDUMP. If 2 APPs have the same App File Name then the RTL gets confused and loads the wrong Window Resource. I would see the new Windows in my old code. I had to rename all the “new system” APPs.