Hi everyone,
I am in front of a problem of convertion.
I am converting a program which needs a lot of references to work.
So, I have built a lot of DLL with VO projects in converting them in X# and setting their output type in "Class Library".
But i have the same error a lot of time :
---Error XS9010 The function 'PCount' is only supported in functions or methods with CLIPPER calling convention (and not in ACCESS or ASSIGN methods)---
I talked with some other persons to find a solution and the only thing they said is :
You have to find manually how many parameters the method needs to have to work and replace "PCount()" by the good number of parameters.
But I have no idea of how I can find this.
Here is an example among many others :
<ACCESS Language()
// property Language
LOCAL a AS ARRAY
LOCAL uRetValue AS USUAL
LOCAL pRetDesc IS VOOLEARGDESC
a := {String2Symbol("Language"), 1, INVOKE_PROPERTYGET, 0, 0, FALSE, NULL, @pRetDesc}
pRetDesc.dwIDLFlag := 0
pRetDesc.dwVarType := VT_I4
uRetValue := SELF:__InvokeMethod(a, DWORD(_bp+16), PCount())
return(uRetValue)>
If someone have something to go forward, it would be amazing.
Have a nice day.
Léo
CLIPPER Calling convention methods
CLIPPER Calling convention methods
Leo,
This is obviously generated code for an automation server.
You should forget about converting this code from VO to .Net.
It simply uses too many undocumented and unsupported features to work in .Net.
However: there is a much better solution in .Net, and it works and is being used by millions of C# and VB users in the world.
Inside Visual Studio you can attach a Automation Server as reference. This will start a tool that creates a .Net wrapper library to communicate with the Automation Server.
I am working on an article that describes step by step on how to do this.
The short version is:
- Create a new app in Visual Studio (lets say a Console App)
- Choose 'Add Reference'
- Select the COM tab in the Add Reference dialog
- Choose the Automation Server (let's say Microsoft ActiveX Data Objects (ADO) which is the Access database engine)
- Click OK
- This will add a reference to your app "ADODB"
- This will create the file "Interop.ADODB.dll" in your apps folder structure
- When you right click on the reference you can open it in the Object Browser to view its contents
- You can then use the code in the generated wrapper like normal .Net code:
Something similar is true for ActiveX controls. VS can also generate type libraries for these.
I will describe all of that in my article
Robert
This is obviously generated code for an automation server.
You should forget about converting this code from VO to .Net.
It simply uses too many undocumented and unsupported features to work in .Net.
However: there is a much better solution in .Net, and it works and is being used by millions of C# and VB users in the world.
Inside Visual Studio you can attach a Automation Server as reference. This will start a tool that creates a .Net wrapper library to communicate with the Automation Server.
I am working on an article that describes step by step on how to do this.
The short version is:
- Create a new app in Visual Studio (lets say a Console App)
- Choose 'Add Reference'
- Select the COM tab in the Add Reference dialog
- Choose the Automation Server (let's say Microsoft ActiveX Data Objects (ADO) which is the Access database engine)
- Click OK
- This will add a reference to your app "ADODB"
- This will create the file "Interop.ADODB.dll" in your apps folder structure
- When you right click on the reference you can open it in the Object Browser to view its contents
- You can then use the code in the generated wrapper like normal .Net code:
Code: Select all
Function Start as VOID
local oConn as AdoDb.Connection
oConn := AdoDb.Connection{}
Console.WriteLine(oConn:Version)
Console.ReadLine()
RETURN
Something similar is true for ActiveX controls. VS can also generate type libraries for these.
I will describe all of that in my article
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
CLIPPER Calling convention methods
Thank you for you help I will try it ! I will read your article obviously.
But a contact I have said this to me :
"Even if you solve the pcount() problem it will not work in the long run because of all the pointers in the code."
And then, this :
"You should approach it in a totally different way.
If you have installed MODI on your system, you can best create a C# project (library).
Reference it to the Microsoft Office Digital Imaging type library.
Then write the methods (Access) like NumChars in C# ."
What do you mean by "Automation Server" ? I don't understand...
I tried what you explained to me, but in the object browser, it created a big library with a lot of methods and functions.
In fact, i have to convert the method you see down there in C# and create a library that contains all of them. But i don't know how to do correspond all the properties and other methods it uses from X# to C#.
Léo
But a contact I have said this to me :
"Even if you solve the pcount() problem it will not work in the long run because of all the pointers in the code."
And then, this :
"You should approach it in a totally different way.
If you have installed MODI on your system, you can best create a C# project (library).
Reference it to the Microsoft Office Digital Imaging type library.
Then write the methods (Access) like NumChars in C# ."
What do you mean by "Automation Server" ? I don't understand...
I tried what you explained to me, but in the object browser, it created a big library with a lot of methods and functions.
In fact, i have to convert the method you see down there in C# and create a library that contains all of them. But i don't know how to do correspond all the properties and other methods it uses from X# to C#.
Léo
CLIPPER Calling convention methods
Leo,
Your contact was right: the VO code will not port.
However there is no need to write a C# wrapper. X# can do all that is needed.
Adding the reference what you contact said is what I suggested as well.
What I mean with automation server is this:
In general there are 2 ways COM is used:
1) To Remote Control an application. Such as opening, modifying and writing office documents with Word or Excel. This is also known as "Automation". For Automation there are 2 sides: the Client and the Server. The Clients uses an API that the Server exposes. I was referring to this as Automation Server
2) Adding a (usually visual) component to an application. For example a Graph control, a Report Viewer control or a PDF viewer control. Components that provide this are known as OCX or ActiveX. They usually also have some kind of Automation Interface, so you can control their behaviour and looks from your code.
Robert
Your contact was right: the VO code will not port.
However there is no need to write a C# wrapper. X# can do all that is needed.
Adding the reference what you contact said is what I suggested as well.
What I mean with automation server is this:
In general there are 2 ways COM is used:
1) To Remote Control an application. Such as opening, modifying and writing office documents with Word or Excel. This is also known as "Automation". For Automation there are 2 sides: the Client and the Server. The Clients uses an API that the Server exposes. I was referring to this as Automation Server
2) Adding a (usually visual) component to an application. For example a Graph control, a Report Viewer control or a PDF viewer control. Components that provide this are known as OCX or ActiveX. They usually also have some kind of Automation Interface, so you can control their behaviour and looks from your code.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
CLIPPER Calling convention methods
UPDATE:
The article Robert mentioned is part of the Xporter examples:
https://www.xsharp.eu/help/example-4-ol ... ation.html
Dick
The article Robert mentioned is part of the Xporter examples:
https://www.xsharp.eu/help/example-4-ol ... ation.html
Dick
CLIPPER Calling convention methods
Replying on #2:
This error is not limited to automation code unfortunately. This is part of the source code of Sven Eberts SEUIEXP menu which should be transportable :
Access ContextMenu(symBandTB)
Local lParam As Logic
Local dwPos As Dword
Local symBand As Symbol
Local sRBHITTESTINFO Is _winRBHITTESTINFO
lParam := PCount() > 0
So it is not OLE automation.
How should I prevent the error here? Problem is that I do have a source code version but I didn't develop this myself so I do not want to change the code wherever possible.
Dick
This error is not limited to automation code unfortunately. This is part of the source code of Sven Eberts SEUIEXP menu which should be transportable :
Access ContextMenu(symBandTB)
Local lParam As Logic
Local dwPos As Dword
Local symBand As Symbol
Local sRBHITTESTINFO Is _winRBHITTESTINFO
lParam := PCount() > 0
So it is not OLE automation.
How should I prevent the error here? Problem is that I do have a source code version but I didn't develop this myself so I do not want to change the code wherever possible.
Dick
CLIPPER Calling convention methods
Hi Dick,
From a quick look, I think it should be enough to change the code to
lParam := .not. IsNil(symBandTB)
but need to see the complete code of the ACCESS to tell you for sure..
Chris
From a quick look, I think it should be enough to change the code to
lParam := .not. IsNil(symBandTB)
but need to see the complete code of the ACCESS to tell you for sure..
Chris
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu