Skip to main content
4-Participant
Jul 17, 2023 8:47 PM UTC
Solved

C++ and C# p/invoke Not Working Cannot Start Creo And Throws AccessViolationException

Hi all,

I'm using Creo Parametric 7.0.2.

 

I'm working on trying to use C# p/invoke interop method to call a Creo function from the C++ toolkit. 

I have a C++ .exe that will include the Creo async functionality. 

 

It exposes these two functions:

 

 

 

 

extern "C" __declspec(dllexport) int ConnectToCreo()
{
	pfcAsyncConnection_ptr connection = pfcAsyncConnection::Start("C:\\Program Files\\PTC\\Creo 7.0.2.0\\Parametric\\bin\\parametric.exe", NULL);
	return 0;
}

extern "C" __declspec(dllexport) int NoCreo()
{
	return -1;
}

 

 

 

 

For the C# side, I created a simple command line app:

 

 

 

 

using System.Runtime.InteropServices;

namespace CreoInteropPoC;

internal class Program
{
 [DllImport("CreoAsync.exe", CallingConvention = CallingConvention.Cdecl)]
 public static extern int ConnectToCreo();

 [DllImport("CreoAsyncDll.exe")]
 private static extern int NoCreo();

 static void Main(string[] args)
 {
 Console.WriteLine(NoCreo());
 ConnectToCreo();
 Console.ReadKey();
 }
}

 

 

 

 

The C# app calls the function NoCreo and works fine but throws an AccessViolationException when calling ConnectToCreo.

 

I have also attached a screenshot of the call stack. 

 

Is it possible to use p/invoke to call Creo functions? Can you point me to what I'm doing wrong?

 

 

 

 

 

 

RPN
RPNAnswer
18-Opal
Jul 19, 2023 8:52 PM UTC

I was wondering about 

DllImport("CreoAsyncDll.exe"

 

Are you sure to use DLL Import by specifying an executable?

I found this, but maybe I‘m wrong. 

From Stackoverflow 

13 replies

RPN
18-Opal
Jul 18, 2023 8:32 PM UTC

You have to use the .bat file or you call the exe with the psf file. In your case you don’t have set any env var, and you don’t start the xtop. See the psf file for more details. 

Translate
4-Participant
Jul 19, 2023 2:21 AM UTC

Hi RPN,

 

Thank you for the reply. I took your suggestion and attempted to pass in the .bat file to the Start function. The C++ code now looks like this:

#include <pfcAsyncConnection.h>
extern "C" __declspec(dllexport) int ConnectToCreo()
{
	pfcAsyncConnection_ptr connection = pfcAsyncConnection::Start("C:\\Program Files\\PTC\\Creo 7.0.2.0\\Parametric\\bin\\parametric.bat", NULL);
	return 0;
}

extern "C" __declspec(dllexport) int NoCreo()
{
	return -1;
}

 The C# code is the same. 

I am still getting the AccessViolationException. I reviewed the .bat file and it calls parametric.exe with my .psf file. I checked the .psf file and it appears to have all the needed environment variables listed. 

 

Any other suggestions?

Translate
17-Peridot
Jul 19, 2023 7:04 AM UTC

Try to connect to an existing running Creo process

 

pfcAsyncConnection::Connect

 

 to localize a problem:

a) in starting Creo

b) in API call

 

By the way, I think, it is possible to start Creo from C# directly

 

PS: take a look API documentation chapter "Task Based Application Libraries"

Translate
RPN
18-Opal
Jul 19, 2023 3:01 PM UTC

I'm not a C# freak, but I checked the example code

 

You have 

extern "C" __declspec(dllexport) int ConnectToCreo()

And if I map this, I think the Code may looks like

 

extern "C" ProError ConnectToCreo ()

 

I'm not sure if you need to export your function, probably not.

 

I think you have to check the sample code in Common Files\otk\otk_cpp\otk_async_examples

 

Because the error tells you to have a general memory issue.

Translate
4-Participant
Jul 19, 2023 7:29 PM UTC

Hi RPN,

 

The reason why I need the __declspec(dllexport) is because I'm exporting this function from the executable. When I take this off I get this error:

 

System.EntryPointNotFoundException: 'Unable to find an entry point named 'ConnectToCreo' in DLL "Path/To/My/DLL'.' which tells me it cannot find my function.

 

I'll review the OTK async examples. And thanks for the ideas so far.

 

 

Translate
RPN
RPN18-OpalAnswer
18-Opal
Jul 19, 2023 8:52 PM UTC

I was wondering about 

DllImport("CreoAsyncDll.exe"

 

Are you sure to use DLL Import by specifying an executable?

I found this, but maybe I‘m wrong. 

From Stackoverflow 

Translate