xsharp.eu • CLIPPER Calling convention methods
Page 1 of 1

CLIPPER Calling convention methods

Posted: Fri Jun 02, 2017 7:06 am
by Anonymous
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

Posted: Fri Jun 02, 2017 8:20 am
by robert
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:

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

CLIPPER Calling convention methods

Posted: Fri Jun 02, 2017 8:46 am
by Leo Groupierre
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

CLIPPER Calling convention methods

Posted: Fri Jun 02, 2017 9:56 am
by robert
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

CLIPPER Calling convention methods

Posted: Sun Feb 17, 2019 5:28 am
by ic2
UPDATE:

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

Posted: Sun Feb 17, 2019 5:42 am
by ic2
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

CLIPPER Calling convention methods

Posted: Sun Feb 17, 2019 1:10 pm
by Chris
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