BPBEE
asked on
Call VB ActiveX exe from C language
I need to call a VB ActiveX exe from C Language and pass a parameter to the exe. I successfully called a simple vb exe with a messagebox that displayed the parameter using the following code.
strcpy(s_cmd, "Project1.exe ");
strcat(s_cmd, lpDS->szDOCNAME);
nResult = system(s_cmd);
I converted a VB ActiveX DLL project to a VB ActiveX Exe project in Project/Settings in Visual Basic. Then I recompiled the project to make the exe. There are three functions in the VB project. I'm wondering how the exe knows which function is the "main" function.
The simple messagebox exe that I created worked but the more difficult ActiveX exe flashes the DOS window and doesn't display the window that the VB ActiveX object was designed to do.
The application I am working with only accepts straight C code and not CPP code. Any ideas are very much appreciated. I've found nothing solid on google or microsoft.com yet. Everyone is more interested in cpp or c#.
Thanks.
strcpy(s_cmd, "Project1.exe ");
strcat(s_cmd, lpDS->szDOCNAME);
nResult = system(s_cmd);
I converted a VB ActiveX DLL project to a VB ActiveX Exe project in Project/Settings in Visual Basic. Then I recompiled the project to make the exe. There are three functions in the VB project. I'm wondering how the exe knows which function is the "main" function.
The simple messagebox exe that I created worked but the more difficult ActiveX exe flashes the DOS window and doesn't display the window that the VB ActiveX object was designed to do.
The application I am working with only accepts straight C code and not CPP code. Any ideas are very much appreciated. I've found nothing solid on google or microsoft.com yet. Everyone is more interested in cpp or c#.
Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I have some code that looks like this for calling the ActiveX exe. JDE2CM.exe is obviously the exe, CMClass is the VB Class and CallCM is the VB function. But this doesn't compile in JDEdwards. Errors below:
#include "C:\WINDOWS\JDE2CM.exe"
...
CoInitialize(NULL);
_CMClassPtr ptr;
ptr.CreateInstance(__uuido f(CMClass) );
ptr->CallCM(lpDS->szDOCNAM E);
CoUninitialize();
Compile errors:
B550413M.c
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x90'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x3'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xff'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xff'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xb8'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x40'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xc8'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xe'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x1f'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xba'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xe'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xb4'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xcd'
C:\WINDOWS\JDE2CM.exe(1) : error C2143: syntax error : missing '{' before '!'
...
this runs endlessly. It seems that C language cannot understand the VB exe.
When I go back to the dll call instead of an exe call, I have something good but I cannot get the pointer to the VB class.function in order to call it. I tried to use dumpbin.exe against the dll to get the real class name. I also tried using OLE Viewer and the disassembly shows _CMCLass as being the class name. Object names are same JDE2CM.dll, CMClass, CallCM. I have the following code:
PFNJDE2CMdll lpJDE2CM; // declares 1st pointer
HINSTANCE hLibrary; // declares 2nd pointer
...
hLibrary = LoadLibrary("c:\\JDE2CM.dl l");
if(hLibrary != NULL)
{
// I think this is where the address is not coming back
lpJDE2CM = (PFNJDE2CMdll) GetProcAddress (hLibrary, "_CMClass");
if(!lpJDE2CM)
FreeLibrary(hLibrary);
else
{
const char *docid = 0;
docid = lpDS->szDOCNAME;
nResult = lpJDE2CM(docid);
}
}
Here is the disassemby:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: JDE2CM.exe
[
uuid(AEE89487-2C47-4576-AE 0C-48B4A81 4C469),
version(1.0)
]
library JDE2CM
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-0 0000000004 6}
importlib("STDOLE2.TLB");
// Forward declare all types defined in this typelib
interface _CMClass;
[
odl,
uuid(909154C4-792D-4B85-8E E2-5D0445F 7DB73),
version(1.0),
hidden,
dual,
nonextensible,
oleautomation
]
interface _CMClass : IDispatch {
[id(0x60030000)]
HRESULT CallCM(
[in, out] BSTR* DocID,
[out, retval] short* );
};
[
uuid(7D1DA072-B236-4AFD-9E C6-BB789A8 1BE0B),
version(1.0),
appobject
]
coclass CMClass {
[default] interface _CMClass;
};
};
Running dumpbin on the DOS command line gives me the following. The function's real names are supposed to be listed underneath the words: "ordinal hint RVA", but I'm guessing that these are generic Windows dll names because they don't seem to be similar to the names that were used in the dll that I have - but I may be wrong on this one because there are addreses to the left of the names.
-------------------------- ---------
C:\Program Files\Microsoft Visual Studio\VC98\Bin>dumpbin /EXPORTS c:\WINDOWS\JD
E2CM.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file c:\WINDOWS\JDE2CM.dll
File Type: DLL
Section contains the following exports for JDE2CM.dll
0 characteristics
40322065 time date stamp Tue Feb 17 09:08:37 2004
0.00 version
1 ordinal base
4 number of functions
4 number of names
ordinal hint RVA name
1 0 00003AEA DllCanUnloadNow
2 1 00003ABE DllGetClassObject
3 2 00003AD4 DllRegisterServer
4 3 00003AA8 DllUnregisterServer
Summary
2000 .data
1000 .reloc
1000 .rsrc
A000 .text
C:\Program Files\Microsoft Visual Studio\VC98\Bin>
-------------------------- ----------
I seem to be so close to the answer but just need one last change to solve the mystery. Any ideas on any of these possibilities??
I have also placed a 125 point question in the VB question area. Any comments on any of this appreciated.
#include "C:\WINDOWS\JDE2CM.exe"
...
CoInitialize(NULL);
_CMClassPtr ptr;
ptr.CreateInstance(__uuido
ptr->CallCM(lpDS->szDOCNAM
CoUninitialize();
Compile errors:
B550413M.c
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x90'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x3'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xff'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xff'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xb8'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x40'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xc8'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xe'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0x1f'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xba'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xe'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xb4'
C:\WINDOWS\JDE2CM.exe(1) : error C2018: unknown character '0xcd'
C:\WINDOWS\JDE2CM.exe(1) : error C2143: syntax error : missing '{' before '!'
...
this runs endlessly. It seems that C language cannot understand the VB exe.
When I go back to the dll call instead of an exe call, I have something good but I cannot get the pointer to the VB class.function in order to call it. I tried to use dumpbin.exe against the dll to get the real class name. I also tried using OLE Viewer and the disassembly shows _CMCLass as being the class name. Object names are same JDE2CM.dll, CMClass, CallCM. I have the following code:
PFNJDE2CMdll lpJDE2CM; // declares 1st pointer
HINSTANCE hLibrary; // declares 2nd pointer
...
hLibrary = LoadLibrary("c:\\JDE2CM.dl
if(hLibrary != NULL)
{
// I think this is where the address is not coming back
lpJDE2CM = (PFNJDE2CMdll) GetProcAddress (hLibrary, "_CMClass");
if(!lpJDE2CM)
FreeLibrary(hLibrary);
else
{
const char *docid = 0;
docid = lpDS->szDOCNAME;
nResult = lpJDE2CM(docid);
}
}
Here is the disassemby:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: JDE2CM.exe
[
uuid(AEE89487-2C47-4576-AE
version(1.0)
]
library JDE2CM
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-0
importlib("STDOLE2.TLB");
// Forward declare all types defined in this typelib
interface _CMClass;
[
odl,
uuid(909154C4-792D-4B85-8E
version(1.0),
hidden,
dual,
nonextensible,
oleautomation
]
interface _CMClass : IDispatch {
[id(0x60030000)]
HRESULT CallCM(
[in, out] BSTR* DocID,
[out, retval] short* );
};
[
uuid(7D1DA072-B236-4AFD-9E
version(1.0),
appobject
]
coclass CMClass {
[default] interface _CMClass;
};
};
Running dumpbin on the DOS command line gives me the following. The function's real names are supposed to be listed underneath the words: "ordinal hint RVA", but I'm guessing that these are generic Windows dll names because they don't seem to be similar to the names that were used in the dll that I have - but I may be wrong on this one because there are addreses to the left of the names.
--------------------------
C:\Program Files\Microsoft Visual Studio\VC98\Bin>dumpbin /EXPORTS c:\WINDOWS\JD
E2CM.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file c:\WINDOWS\JDE2CM.dll
File Type: DLL
Section contains the following exports for JDE2CM.dll
0 characteristics
40322065 time date stamp Tue Feb 17 09:08:37 2004
0.00 version
1 ordinal base
4 number of functions
4 number of names
ordinal hint RVA name
1 0 00003AEA DllCanUnloadNow
2 1 00003ABE DllGetClassObject
3 2 00003AD4 DllRegisterServer
4 3 00003AA8 DllUnregisterServer
Summary
2000 .data
1000 .reloc
1000 .rsrc
A000 .text
C:\Program Files\Microsoft Visual Studio\VC98\Bin>
--------------------------
I seem to be so close to the answer but just need one last change to solve the mystery. Any ideas on any of these possibilities??
I have also placed a 125 point question in the VB question area. Any comments on any of this appreciated.
ASKER
The code that I wrote with your help called the ActiveX dll, unfortunately it did not run under our old version 7.33 of J.D. Edwards - complaining about cpp code. Only C language allowed here. I thought that everything was Ok, but did not do well in Test Environment.
I have now decided to change the VB ActiveX dll to an exe. During a small test, I was able to pass a parameter to a VB exe and display the value in a messagebox. This prompted me to try the ActiveX exe. I'm not 100% sure that this is a good move.
Changing the VB ActiveX dll to an exe is simple. I have also unregistered the dll - just in case. I am unsure how to startup the correct VB function (method). This VB code comes from a software vendor and I am relectant to change the code itself, although changing the settings may be Ok.
I am thinking I should create a VB Standard exe to call the ActiveX exe (or dll) and call the VB Standard exe from J. D. Edwards C language code. Are there any VB experts out there with any advice on this move?