Hi Juraj, hi Jamal,
will prepare it tomorrow morning.
Wolfgang
Expose X# run-time functions to C#
Expose X# run-time functions to C#
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Expose X# run-time functions to C#
Hi Chris,
I created an X# code file with something like the following. Named DLL as MyXSharpClassLibrary.
When opening the a DBF in X# where the CDX key expression contains the above, the DBF opens fine and I also the function is accessible in regular code.
Now in C# I tried adding the attribute to the C# project
[assembly: XSharp.Internal.ClassLibrary("MyXSharpClassLibrary", "")]
namespace Test
{
// code ...
}
But this causes the following compile time error.
causes Severity Code Description Project File Line Suppression State
Error CS0579 Duplicate 'XSharp.Internal.ClassLibrary' attribute
[assembly: XSharp.Internal.ClassLibrary("MyRuntimeFuncsClass", "")]
Any clue what might be wrong?
Thanks!
Jamal
I created an X# code file with something like the following. Named DLL as MyXSharpClassLibrary.
Code: Select all
USING System
USING System.Collections.Generic
USING System.Text
FUNCTION TestFunction() AS STRING
RETURN "Test"
Now in C# I tried adding the attribute to the C# project
[assembly: XSharp.Internal.ClassLibrary("MyXSharpClassLibrary", "")]
namespace Test
{
// code ...
}
But this causes the following compile time error.
causes Severity Code Description Project File Line Suppression State
Error CS0579 Duplicate 'XSharp.Internal.ClassLibrary' attribute
[assembly: XSharp.Internal.ClassLibrary("MyRuntimeFuncsClass", "")]
Any clue what might be wrong?
Thanks!
Jamal
Expose X# run-time functions to C#
Hi Jamal,
Maybe indeed you accidentally defined this attribute twice?
Also you need to specify the class name (complete, including the namespace) in the first parameter, not the assembly name of the library, but that has to do with the runtime behavior only of course.
Maybe indeed you accidentally defined this attribute twice?
Also you need to specify the class name (complete, including the namespace) in the first parameter, not the assembly name of the library, but that has to do with the runtime behavior only of course.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Expose X# run-time functions to C#
Hello,
I have now prepared the library (it differs from the one I'm using internally because I have removed some non-needed classes).
You can find it here:
https://riedmann.it/download/XbaseInterface.zip
I have included the binaries, the single source files and a XIDE export file.
The most interesting class may be the XbDate class as it shows how the define your own datatype including the support for operators.
All these classes are used in production, but of course will contain errors and be incomplete.
Wolfgang
I have now prepared the library (it differs from the one I'm using internally because I have removed some non-needed classes).
You can find it here:
https://riedmann.it/download/XbaseInterface.zip
I have included the binaries, the single source files and a XIDE export file.
The most interesting class may be the XbDate class as it shows how the define your own datatype including the support for operators.
All these classes are used in production, but of course will contain errors and be incomplete.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Expose X# run-time functions to C#
Hi Chris,
Hopefully, you can spot why the macro compiler cannot see the custom X# function which is part the key expression when being a DBF is opened in C#. I attached test.zip which contains the projects and sample dbf and cdx.
I've created a X# DLL named: MyXSharpClassLibrary which has a Code File.
I declared a function KeyExp() which is used as part of an CDX Index expression, for example:
DbCreateOrder("FIRST", cDbf,"Upper(FIRST)+KeyExp()")
This is just a sample and it can be more complex and longer; It is easier to manage.
Create test dbf with CDX orders in X#. I added a reference to the MyXSharpClassLibrary. No issues here.
I created a C# app and added MyXSharpClassLibrary reference the the C# app. The app compiles fine.
Please see the attached screenshot of error message with InnerException: Exception of type 'XSharp.RDD.RddError' was thrown. and SubCodeText: "Expression for macro compiler left"
Which indicates that the Macro Compiler cannot see the KeyExp() function and thus fails to open the DBF file.
What I am doing wrong
Hopefully, you can spot why the macro compiler cannot see the custom X# function which is part the key expression when being a DBF is opened in C#. I attached test.zip which contains the projects and sample dbf and cdx.
I've created a X# DLL named: MyXSharpClassLibrary which has a Code File.
I declared a function KeyExp() which is used as part of an CDX Index expression, for example:
DbCreateOrder("FIRST", cDbf,"Upper(FIRST)+KeyExp()")
This is just a sample and it can be more complex and longer; It is easier to manage.
Code: Select all
USING System
USING System.Collections.Generic
USING System.Text
using System.Runtime.CompilerServices
using XSharp
using XSharp.Internal
using XSharp.RT
function KeyExp() as string
return iif(_FIELD->FIRST > "R", "Y", "N")
Code: Select all
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
using System.Runtime.CompilerServices
using XSharp
using XSharp.Internal
using XSharp.RT
using MyXSharpClassLibrary
FUNCTION Start() AS VOID STRICT
LOCAL cDbf AS STRING
cDbf := "c:testmynewtest"
RddInfo(_SET_AUTOOPEN, true)
RddSetDefault("DBFCDX")
DbCreate(cDbf , {{"LAST" , "C" , 10,0}, {"FIRST", "C", 10, 0}})
DbUseArea(true, "DBFCDX", cDbf, "mynewtest", false, false)
? DbCreateOrder("FIRST", cDbf,"Upper(FIRST)+KeyExp()")
? DbCreateOrder("LAST", cDbf,"Upper(LAST)")
LOCAL aValues, aValues2 AS ARRAY
aValues := {"JACK", "MARK", "HARRY", "Mary", "ROB", "SALLY"}
aValues2 := {"MAC", "JIM", "paul", "SUE", "THERE", "ELF"}
FOR LOCAL n := 1 AS DWORD UPTO ALen(aValues)
DbAppend()
FieldPut(1,aValues[n])
FieldPut(2,aValues2[n])
NEXT
DbGoTop()
WHILE !EOF()
? FieldGet(1), FieldGet(2)
DbSkip(1)
END
?
? "Set order: "
? DbSetOrder("FIRST")
DbGoTop()
WHILE !EOF()
? FieldGet(1), FieldGet(2)
DbSkip(1)
END
? "Records:", LastRec()
? DbSetOrder("LAST")
DbGoTop()
WHILE !EOF()
? FieldGet(1), FieldGet(2)
DbSkip(1)
END
DbCloseArea()
WAIT
RETURN
Code: Select all
using System;
using System.Windows.Forms;
using XSharp;
using XSharp.RT;
using XSharp.VO;
using XSharp.RDD;
using XSharp.Internal;
using XSharp.Core;
[assembly: XSharp.Internal.ClassLibrary("Functions", "MyXSharpClassLibrary")] // is this correct ??
namespace DBFCDX_CS_Sample
{
public partial class Form1 : Form
{
public const int RDD_INFO = 100;
public const int _SET_AUTOOPEN = RDD_INFO + 4;
public const int _SET_AUTOORDER = RDD_INFO + 5;
public Form1()
{
InitializeComponent();
}
private void ReservationsDBFbutton_Click(object sender, EventArgs e)
{
XSharp.CoreDb.RddInfo(_SET_AUTOOPEN, true);
if (XSharp.RT.Functions.DbUseArea(true, "DBFCDX", @"C:testmynewtest.dbf", "newtestdbf", true, false))
{
XSharp.RT.Functions.DbSetOrder("LAST");
// MessageBox.Show(XSharp.RT.Functions.FCount().ToString());
MessageBox.Show(XSharp.RT.Functions.LastRec().ToString());
XSharp.RT.Functions.VoDbCloseArea();
}
}
}
}
Which indicates that the Macro Compiler cannot see the KeyExp() function and thus fails to open the DBF file.
What I am doing wrong
Chris wrote:Hi Jamal,
Maybe indeed you accidentally defined this attribute twice?
Also you need to specify the class name (complete, including the namespace) in the first parameter, not the assembly name of the library, but that has to do with the runtime behavior only of course.
- Attachments
-
- test.zip
- (1.69 MiB) Downloaded 70 times
Expose X# run-time functions to C#
Hi Jamal,
I found the problem, it's just because the library has not been loaded yet, so the macro compiler cannot find the function in it. To ensure it is loaded, just add a call to any function of this library in your code, before opening the dbf. now it should work. (just ignore the return value of your function call).
About:
[assembly: XSharp.Internal.ClassLibrary("Functions", "MyXSharpClassLibrary")] // is this correct ??
No, this would be needed only if you wanted the macro compiler to see functions defined in your _c#_ library, in which case you would need to specify the name of the c# class that holds your functions (methods) in the first param (and keep the 2nd param empty). In the case of X# libraries, the macro compiler already knows where to search for functions, so you do not need this attribute.
I found the problem, it's just because the library has not been loaded yet, so the macro compiler cannot find the function in it. To ensure it is loaded, just add a call to any function of this library in your code, before opening the dbf. now it should work. (just ignore the return value of your function call).
About:
[assembly: XSharp.Internal.ClassLibrary("Functions", "MyXSharpClassLibrary")] // is this correct ??
No, this would be needed only if you wanted the macro compiler to see functions defined in your _c#_ library, in which case you would need to specify the name of the c# class that holds your functions (methods) in the first param (and keep the 2nd param empty). In the case of X# libraries, the macro compiler already knows where to search for functions, so you do not need this attribute.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Expose X# run-time functions to C#
Hi Chris,
Wow! That worked great!!
Thanks!
Jamal
Wow! That worked great!!
Thanks!
Jamal
Expose X# run-time functions to C#
Hi Chris,
In the mean time I found another way to load the assembly without creating a dummy function. I only had to call:
Oh man! I could have saved hours by knowing this.
Thanks!
Jamal
In the mean time I found another way to load the assembly without creating a dummy function. I only had to call:
Code: Select all
System.Reflection.Assembly.Load("MyXSharpClassLibrary");
Thanks!
Jamal
Expose X# run-time functions to C#
Hi Jamal,
You're welcome! First time I had this I also lost many hours! This time it took much lessJamal wrote:Hi Chris,
In the mean time I found another way to load the assembly without creating a dummy function. I only had to call:
Oh man! I could have saved hours by knowing this.Code: Select all
System.Reflection.Assembly.Load("MyXSharpClassLibrary");
Thanks!
Jamal
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu