Clarion 11 call C# dll will show Exception screen

I am using Clarion 11 to call C# dll, once invoke C# function, it will appear Exception Screen.

Any idea of this issue? I use MGLibMkr.exe to generate lib.

Thank you.

Regards,
Nelson

Clarioners are the only people on Earth who don’t know what a debugger is for.

2 Likes

What is C# function your program tries to call?
How it is prototyped on the C# and Clarion sides?
What are actual parameters passed to the call and their types?

2 Likes

More like only ones not really knowing how to use it. Myself included, tbh.

We’d like to be able to help you
But we need so much more information.
Some of the first thoughts that come to mind are:

  1. What does the call look like on the clarion side?
  2. How to improve the Call Stack when your program GPFs to show Procedure Names - ide / Tips - ClarionHub
  3. Are there parameters
  4. Is the call wrapped in a class
    a) if so are there LINK/MODULE attrubutes?
    i) do you have your pragma’s set
    ii) is the include for the class at a global (or module) scope ?
  5. is the .NET program configured for x86 ?
  6. when exactly does the crash occur?
    a) as you make the call
    b) upon return from the call
2 Likes

Also, if you have the source for the C# DLL, you can open the running Clarion process in VS and Debug the C# DLL, if that’s where the crash occurs.

1 Like

Thanks all for helping.

This is simple C# DLL which configured for x86. I not passing any parameter over, because Clarion don’t have DateTime.Now.Ticks function, so I let C# generate it and pass back to me.

I use MGLibMkr to generate Lib and added to my App Library Object. GenerateRandomString() is the C# function name.

I just code → LocRandomStr = GenerateRandomString(), and it able return me correct value, and finish all the code after it without GPF, GPF occurred when finished Embed point coding.

If I set Debug Info → Full. no GPF will appear.

Thank you.

Nelson - not directly answering your gpf problem but is there any reason you are using a C# dll to do this when you could just use Clarion code to generate a random string?

Clarion got C# “DateTime.Now.Ticks” function?

My vendor using a lot C# function, I use this as testing purpose.

TQ

Show your Code how you declared GenerateRandomString() in Clarion?

And the C# Code?

You’re missing something (like PASCAL) or have something wrong (like C). We cannot help you without some Code.

The way I read it that returns a 64 bit INT. Clarion is 32 bit so you’ll be losing 32 bits.

You may be able to code it as a REAL return in Clarion which is 64 bits. Then put an Int64 Over that Real. Better would be to code it on both sides as (*Long Hi64, *LONG Lo64) and no return.

In Clarion you write Code. Here we help you fix your Code. You MUST POST YOUR CODE for us to help.

1 Like

Why do you need to use DateTime.Now.Ticks in the first place? Depending on what you’re trying to do there might be a Clarion solution and you don’t need c# at all.

DateTime.Now in C# is nothing else as value returned from the call to GetSystemTimeAsFileTime Windows API function converted to “ticks”. One “tick” is a 1/10000000 of second. If you don’t need in nano-second resolution (which is calculated really, actual resolution is dependent from Windows version and hardware and counting in milliseconds), you can use API functions like GetSystemTime or GetSystemTimeAsFileTime. API functions QueryPerformanceCounter and QueryPerformanceFrequency can be used for calculations of time elapses with he most possible actual resolution.

What is Clarion prototype of GenerateRandomString? What is type of LocRandomStr?
Strings in managed code are Unicode. It’s need to use Marshal.StringToBSTR to get the pointer to an Unicode strings usable in native code. Then, Unicode string pointed by the pointer returned from Marshal.StringToBSTR can be converted to an ANSI string.

I guess, you had in mind that the described code was coded in some embed point and the exception occurred on the exit from this code. Am I right? For me, the most probable reasons for the exception are:

  • memory overrun on the “random” string storing
  • incorrect invalidation of some object on the C# side.
1 Like

If somebody interested, here is the implementation of DateTime.Now from .Net reference sources:

        // Returns a DateTime representing the current date and time. The 
        // resolution of the returned value depends on the system timer. For
        // Windows NT 3.5 and later the timer resolution is approximately 10ms, 
        // for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98 
        // it is approximately 55ms.
        // 
        public static DateTime Now {
            get {
                return UtcNow.ToLocalTime();
            } 
        }
 
        public static DateTime UtcNow { 
            get {
                // following code is tuned for speed. Don't change it without running benchmark. 
                long ticks = 0;
                ticks = GetSystemTimeAsFileTime();
                return new DateTime( ((UInt64)(ticks + FileTimeOffset)) | KindUtc);
            } 
        }

Think it’s just to try using C#… He said:

My vendor using a lot C# function, I use this as testing purpose.

I think it may be caused by uncoordinated registers’ Push and Pop caused by a bad prototype definition of the function called, leaving parameters leaked on the stack or the opposite double cleaning them. As by his description the problem arise at Clarion function return and only in release mode, not in debug mode, which generates code relying on base pointer.

This is possible but if to take into account the call stack shown in the posted exception message (exception is inside code external for the program) and the information that exception was at exit from the test code, incorrect prototypes are unlikely the reason. Though, some chances exist.

Always though the DOT NET DLL and win 32 were not compatible.

If you are using C# code, its mandatory, in c# code to catch exception inside c# code or you get exactly your gpf… As always, if some error occured in c# code, and you do not try to catch it, this appear…
So, examine a little try and catch…

1 Like

My Clarion app need to integrate with Vendor payment device, he provide API code in C#.

This is one sample :-

using System;
using System.Text;

namespace RevenueMonsterOpenAPI.Util
{
internal class RandomString
{
//private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private static readonly Random Random = new Random((int)DateTime.Now.Ticks);
public static string GenerateRandomString(int size)
{
var builder = new StringBuilder();
for (var i = 0; i < size; i++)
{
var ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * Random.NextDouble() + 65)));
builder.Append(ch);
}

        return builder.ToString();
    }
}

}

There are a lot function in C# API they provided need integrate with. So, I decide compiled it in C# dll and clarion call will be simple way.

Thank you for all reply.

Not-managed code can’t use managed strings directly. Use Marshal.StringToBSTR for conversion.