How to call C# project function from C++ DLL project - c#

I have two project, say named CPPDLLProject and CSharpProject.
Here in CPPDLLProject, there are few dllexport functions which can be called from CSharpProject and that calling is working fine.
But here I want to call CSharpProject's functions from CPPDLLProject so that can propagate data from C++ DLL to C# project.
Just for more explanation, Would like to add below code example.
Below is the function in the C++ DLL from which would like to call C# functions.
void __stdcall CPPDLLApp::PumpMessageData(int aCode, int aType)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (aCode == PUMP_UPDATE_MSG && aData != NULL)
{
switch (aType)
{
case MSG_ADD:
{
// Call the C# function to send the added msg to C# project
GetCPPDLLAppMsg("MSG added");
break;
}
case MSG_DELETE:
{
// Call the C# function to send the deleted msg to C# project
GetCPPDLLAppMsg("MSG deleted");
break;
}
case MSG_UPDATE:
{
// Call the C# function to send the updated msg to C# project
GetCPPDLLAppMsg("MSG updated");
break;
}
}
}
if (aCode == PUMP_STOP_MSG)
{
// Call the C# function to send the stop msg to C# project
break;
}
if (aCode == PUMP_START_MSG)
{
// Call the C# function to send the start msg to C# project
break;
}
}
Below is the C# project's function.
public void GetCPPDLLAppMsg(string aMessage)
{
Console.WriteLine(aMessage);
}
Please suggest how to achieve this goal.
I have done few googling but no luck.
My question might not be clear but any kind of help is appreciated.

I don't really understand your question, but you can use a intermediate dll and the following C++ method:
void *p = (void *)wglGetProcAddress(name);
if (p == 0 ||
(p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) ||
(p == (void*)-1))
{
HMODULE module = LoadLibraryA("dllname.dll");
p = (void *)GetProcAddress(module, name);
}
name = name of the function
dllname = name of your dll
with this you will be able to load a dll and get the function pointer to wichever function you need, but you may need to compile a C# dll to use this, you can make a bridge or something

Related

Access violation Error in C#

I have C# windows form project on VS2013.
my graphic support by MFC C++ project through dll.
when I use 32 bit dll and 32bit C# project it's work fine.
but when use 64bit dll and 64bit C# project only work with .net framework 4 client profile and not work on .net framework 4.5 and get access violation error when use dll.
code that throw access violation error on C++ dll.
BOOL ImportElevation( CString &csFileName )
{
CString csTmpPath = GetTempFolderName(csFileName.GetBuffer());
int iResult = vtCreateDir(csTmpPath);
if (iResult == 0 && errno != EEXIST)
{
MessageBox(NULL,_T("Couldn't create temporary directory to hold contents of archive."),
_T("Error"),MB_ICONERROR);
return FALSE; // no layers created
}
CString csUnzipPath = csTmpPath + _T("/");
iResult = ExpandZip(csFileName, csUnzipPath, ProgressCallback);
if (iResult == 1)
{
// the archive contained a single file
std::string strPathName = (const char *) csUnzipPath;
for (dir_iter it(strPathName); it != dir_iter(); ++it)//at this line throw exception
{
if (it.is_directory())
continue;
csUnzipPath += it.filename().c_str();
break;
}
CElevLayer* pLayer = new CElevLayer(csFileName);
if(pLayer->ImportElevation(csUnzipPath,TRUE,ProgressCallback))
{
m_vecElevLayer.push_back(pLayer);
m_iActiveLayerIdx = m_vecElevLayer.size()-1;
pLayer->CreateMap(ProgressCallback);
return TRUE;
}
else
SAFE_DELETE(pLayer);
return FALSE;
}
// clean up after ourselves
csTmpPath = GetTempFolderName(csUnzipPath);
vtDestroyDir(csTmpPath);
return TRUE;
}
I run this dll on 3 different projects and get this error.

Convert from C to C#, or make DLL? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am new to C# programming. I have a program that I modified in C, I now need to take the string array that I get from my C program and pass it to a C# program so that it can query an Oracle database using those values.
This program is used to get the serial numbers from all of the iButton devices connected to the computer.
Here is the C code
// function prototypes
void UnLoadTMEX(void);
short LoadTMEX(void);
// globals
static FARPROC Get_Version, TMGetTypeVersion, TMEndSession;
static FARPROC TMSetup, TMNext, TMRom, ExtendedStartSession;
static FARPROC TMReadDefaultPort;
long (__fastcall *TMExtendedStartSession)(short,short,void *);
static HINSTANCE hInst;
unsigned char state_buf[5125];
//--------------------------------------------------------------------------
// Main of iSerial64
//
void main(int argc, char **argv)
{
char refresh,buf[200];
short flag,i,didsetup=0;
short ROM[9];
short PortNum,PortType;
long SHandle;
char serialtmp[2], serial[10][17];
int j = -1;
// load the TMEX driver and get pointers to functions
if (!LoadTMEX())
{
printf("ERROR, could not load IBFS64.DLL\n");
exit(0);
}
// load the TMEX driver and get pointers to functions
TMReadDefaultPort(&PortNum, &PortType);
// get the TMEX driver version
printf("Port number: %d Port type: %d\n",PortNum,PortType);
Get_Version(buf);
printf("Main Driver: %s\n",buf);
printf("TYPE%d:",PortType);
if ((short)TMGetTypeVersion(PortType,buf) < 0)
{
printf("\nNo Hardware Driver for this type found!\n");
// Unload the TMEX driver
UnLoadTMEX();
exit(0);
}
printf(" %s\n\n\n",buf);
// check the command line
if (argc > 1)
PortNum = atoi(argv[1]);
// check for valid range of PortNum
if ((PortNum < 1) || (PortNum > 15))
{
printf("ERROR, invalid port requested: %d\n",PortNum);
exit(0);
}
// loop to display the rom numbers until key hit
do
{
// get a session handle to the requested port
SHandle = TMExtendedStartSession(PortNum,PortType,NULL);
if (SHandle > 0)
{
// check to see if TMSetup has been done once
if (!didsetup)
{
flag = (short)TMSetup(SHandle);
if (flag == 1 || flag == 2)
{
printf("TMSetup complete %d\n",flag);
didsetup = 1;
}
else
{
printf("ERROR doing setup %d\n",flag);
break;
}
}
// only get the next rom after setup complete
else
{
//j was added to keep track of the serial number strings
j++;
memset(serial[j], 0, strlen(serial[j]));
flag = (short)TMNext(SHandle,(void far *)&state_buf[0]);
if (flag > 0)
{
ROM[0] = 0;
flag = (short)TMRom(SHandle, (void far *)&state_buf[0], (short far *)&ROM[0]);
for (i = 7; i >= 0; i--)
{
//This section was changed from the original
//copies raw number into string
sprintf(serialtmp, "%02X", ROM[i]);
strcat(serial[j], serialtmp);
}
printf("%s ", serial[j]);
printf("\n");
}
else
printf("end of search\n");
}
// close the opened session
TMEndSession(SHandle);
}
}
while (flag > 0);
// Unload the TMEX driver
UnLoadTMEX();
printf("iSERIAL64 end\n");
}
//--------------------------------------------------------------------------
// Load the TMEX driver and get a pointers to the functions
//
short LoadTMEX(void)
{
// attempt to get a SHandle to the TMEX driver
hInst = LoadLibrary(L"IBFS64.DLL");
// get a pointer to the function needed by loopit64
if (hInst != NULL)
{
ExtendedStartSession = GetProcAddress(hInst,"TMExtendedStartSession");
TMEndSession = GetProcAddress(hInst,"TMEndSession");
TMSetup = GetProcAddress(hInst,"TMSetup");
TMNext = GetProcAddress(hInst,"TMNext");
TMRom = GetProcAddress(hInst,"TMRom");
Get_Version = GetProcAddress(hInst,"Get_Version");
TMGetTypeVersion = GetProcAddress(hInst,"TMGetTypeVersion");
TMReadDefaultPort = GetProcAddress(hInst, "TMReadDefaultPort");
// check to make sure got ALL of the functions needed
if ((ExtendedStartSession == NULL) || (TMEndSession == NULL) ||
(TMSetup == NULL) || (TMNext == NULL) ||
(TMRom == NULL) || (Get_Version == NULL) ||
(TMGetTypeVersion == NULL) || (TMReadDefaultPort == NULL))
{
printf("ERROR, could not get a pointer to all"
" of the TMEX functions needed\n");
return 0;
}
// get a function pointer that returns a long
TMExtendedStartSession = (long (__fastcall *)(short,short,void *))ExtendedStartSession;
return 1;
}
else
return 0;
}
//--------------------------------------------------------------------------
// UnLoad the TMEX driver
//
void UnLoadTMEX(void)
{
// release the TMEX driver
FreeLibrary(hInst);
}
Should I attempt to convert this, or just create a C DLL and import that into my C# program? Like I said, I haven't really worked with C#, I'm an intern and my boss is giving me this project so that I can learn C#. Any help is greatly appreciated
If you want use c dll in c# read this article.
But is better that convert the code to c# code because you can manage this code and update the code easily.
If your boss is giving you this project to learn C#, I'd say go ahead and convert it to C#. It will make future use of the code a lot easier.
I'd recommend looking at the book C# in Depth for a good intro to C#.

How do i convert a C++ function in c# function

I am working on Amibroker C# plugin project. Amibroker SDK is written in C++ but, I am using a C# plugin which does exactly what Amibroker C++ does C# Plugin link
Everything in C# plugin works just fine except one function which is written in c++ this way:
PLUGINAPI struct RecentInfo* GetRecentInfo(LPCTSTR ticker)
{
//Process & return RecentInfo* (RecentInfo is a structure)
}
In C# standard plugin it has been converted this way
public RecentInfo GetRecentInfo(string ticker)
{
//Process & Return RecentInfo
}
Unfortunately, Amibroker application crashes with this wrong conversion. So I did try to convert it my way to get Amibroker App working, but failed multiple times
This is what i have tried so far:
Attemp 1:
unsafe public RecentInfo* GetRecentInfo(string ticker)
{
//Process & Return RecentInfo* (RecentInfo structure is declared as unsafe)
}
Impact:
Amibroker app does not load
Attemp 2:
public IntPtr GetRecentInfo(string ticker)
{
//Process & Return Pointer using Marshal.StructureToPtr
}
Impact:
Amibroker app does not load
Attemp 3:
public void GetRecentInfo(string ticker)
{
//Useless becoz no return type
}
Impact:
Amibroker loads & does call function correctly but how do return a structure pointer
So, I am scratching my head to find out the exact conversion of C++ function in C#
If it is fully written in c# then , this is pretty well ,think there is problem in implementation not in calling
public RecentInfo GetRecentInfo(string ticker)
{
RecentInfo rc;
//Process & Return RecentInfo
return rc;
}
or this , (you can use ref too)
public void GetRecentInfo(string ticker,out RecentInfo rc )
{
rc=new RecentInfo();
....process
return ;
}

Cosmos custom OS, addmapping?

I am new to C# and is currently using COSMOS to make a simple FileSystem for my OS class. Currently I'm trying to implement a "reformat" function that, when the word "reformat" is typed into the console, the OS (emulated via QEMU), partitions the disk. Currently this is my code:
public static void console()
{
while (true)
{
Console.WriteLine("Console: ");
String input = Console.ReadLine();
if (input == "exit")
{
Cosmos.Sys.Deboot.ShutDown();
}
else if (input == "cpumem")
{
Console.WriteLine(Cosmos.Kernel.CPU.AmountOfMemory.ToString());
}
else if (input == "restart")
{
Cosmos.Sys.Deboot.Reboot();
}
else if (input == "devices")
{
var devices = Cosmos.Sys.FileSystem.Disk.Devices.ToArray();
}
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
}
}
Most important is this bit:
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
Which is analogous to what is located here: http://cosmos-tutorials.webs.com/atafat.html
However, when I run it, I get this error:
I believe this is because I lack this line:
Cosmos.System.Filesystem.FileSystem.AddMapping("C", FATFS);
FATFileList = FATFS.GetRoot();
Located in the link above. Is there any other way to map? Or am I missing something completely? The COSMOS documentation doesn't really tell much, the source code is honestly confusing for a beginner like me as it has no comments whatsoever on how the functions work or what they do. I am using an older version of COSMOS (Milestone 4) as it's the only one that works for Visual Studio C# 2008. Newer versions run only in Visual Studio C# 2010.
Ah, I recognize this... had to debug a similar situation on a Cosmos project I'm working on myself (I'm using the VS2010-compatible Cosmos but the same situation might apply to older versions as well...)
This can happen if you try to call a method on a null object. Type 0x........, Method 0x........ is specifically mentioning the location in the compiled code where the call failed. "Not FOUND!" means that the method it is looking for cannot be found, presumably because you called it on a null reference.
I'm testing with VirtualBox myself, and found that if you're using a brand-new blank hard disk image, there will be no Partitions on it. Thus, the condition will never get satisfied, your Partition will never get set and then Cosmos will try to execute a method on the null Partition!
Look closely at how you set the Partition (it's initialized to null). For starters I would print a simple message each time the "if (block device is partition)" condition is satisfied... I would be willing to bet it will never print.
Hope this helps... I am still learning about Cosmos and custom kernels myself but fixing the null reference in my case solved my occurrence of the problem. If that's the problem, then the next step, of course, is figuring out why you're not getting any Partitions in the first place...
The rest of your code looks fine but I am not sure how you implemented the rest of your classes. Kernel debugging can be a nightmare, good luck to you!

FreeImage on C#

I've downloaded the latest compiled version of FreeImage, then build FreeImageNet wrapper. Put FreeImage.dll and FreeImageNet.dll on the same folder as my executable (the sample code). But everytime I run it, it says freeimage.dll is missing. I modified the code on FreeImageWrapper.cs and remove the exception handler
public static bool IsAvailable()
{
/*try
{*/
// Call a static fast executing function
Version nativeVersion = new Version(GetVersion());
Version wrapperVersion = GetWrapperVersion();
// No exception thrown, the library seems to be present
return
(nativeVersion.Major > wrapperVersion.Major) ||
((nativeVersion.Major == wrapperVersion.Major) && (nativeVersion.Minor > wrapperVersion.Minor)) ||
((nativeVersion.Major == wrapperVersion.Major) && (nativeVersion.Minor == wrapperVersion.Minor) && (nativeVersion.Build >= wrapperVersion.Build));
}
/*catch (DllNotFoundException)
{
return false;
}
catch (EntryPointNotFoundException)
{
return false;
}
catch (BadImageFormatException)
{
return false;
}*/
}
It always throws BadImageFormatException. It seems the problem is on the native dll (freeimage.dll) ?
How do I fix it ?
Thanks in advance.
I'm using Visual C# 2010 Express
This happens very often if you try to load a unmanaged 32bit dll into a 64bit process. To get around this problem open the properties of your startup project and change under Built - PlatformTarget the type from Any CPU to x86.

Categories

Resources