News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

problems when I include assembler code in C++ function

Started by Jovanna, May 13, 2019, 09:54:17 PM

Previous topic - Next topic

Jovanna

Hi All,
I have some problems when I include assembler code in  C++ function wrapped in a class. C++ code is compiled to 86 bit dll which is a part of a  WPF .NET project,
compiled for 86,
I use P/Invoke, not C++/ CLI
I am working on Visual Studio 2017
The app starts on my pc, but it crashes when I run it on different virtual Machines, 64,  32, ... I think couldn't add dll...
I am new in assembler, is my code correct? May be I have to write inside assembler function something more? Here is my code:

int MyClass::Foo_1()
{
   __asm
   {
      mov eax, 0      
   }
}
void MyClass::SetFoo_1()
{
   resultEAX = new int;   
   int a = -1;
   try
   {
      a = Foo_1();            
   }
   catch (int e) { }

   if (a == 0) {
      *resultEAX = 0;
   }
   else {
      *resultEAX = 1;
   }      
}

MyClass:
#ifndef MYCLASS_H
#define MYCLASS_H

class __declspec(dllexport) MyClass
{
public:   
   int * resultEAX ;
   
   int Foo1();   
   void SetFoo_1();
   int  GetEAX();
};
#endif


**
extern "C" {
#endif   
   __declspec(dllexport) MyClass* Create();
   __declspec(dllexport) void Dispose(MyClass* a_pObject);
   __declspec(dllexport) void SetFoo_1(MyClass* a_pObject);
   __declspec(dllexport) int GetEAX(MyClass* a_pObject);

#ifdef __cplusplus
}
#endif

**

And I call the class from WPF .NET using managed C# code:
Int32 a = 0;
  IntPtr pMyClass = MyClassHandling.Create();
            Int64 b = 0;
            long c = 0;
            long rslt = 0;

            try
            {
                MyClassHandling.SetFoo_1(pMyClass);


                if (Environment.Is64BitOperatingSystem)
                {
                    //"SysWOW64"
                    b = MyClassHandling.GetEAX(pMyClass);                   
...
                }
                else
                {
                    //"system32"
                    a = pMyClassHandling.GetEAX(pGraphics);
...
                }

MyClassHandling.Dispose (pGraphics);
pMyClass = IntPtr.Zero;


LiaoMi

Quote from: Jovanna on May 13, 2019, 09:54:17 PM
Hi All,
I have some problems when I include assembler code in  C++ function wrapped in a class. C++ code is compiled to 86 bit dll which is a part of a  WPF .NET project,
compiled for 86,
I use P/Invoke, not C++/ CLI
I am working on Visual Studio 2017
The app starts on my pc, but it crashes when I run it on different virtual Machines, 64,  32, ... I think couldn't add dll...
I am new in assembler, is my code correct? May be I have to write inside assembler function something more? Here is my code:

int MyClass::Foo_1()
{
   __asm
   {
      mov eax, 0      
   }
}
void MyClass::SetFoo_1()
{
   resultEAX = new int;   
   int a = -1;
   try
   {
      a = Foo_1();            
   }
   catch (int e) { }

   if (a == 0) {
      *resultEAX = 0;
   }
   else {
      *resultEAX = 1;
   }      
}

MyClass:
#ifndef MYCLASS_H
#define MYCLASS_H

class __declspec(dllexport) MyClass
{
public:   
   int * resultEAX ;
   
   int Foo1();   
   void SetFoo_1();
   int  GetEAX();
};
#endif


**
extern "C" {
#endif   
   __declspec(dllexport) MyClass* Create();
   __declspec(dllexport) void Dispose(MyClass* a_pObject);
   __declspec(dllexport) void SetFoo_1(MyClass* a_pObject);
   __declspec(dllexport) int GetEAX(MyClass* a_pObject);

#ifdef __cplusplus
}
#endif

**

And I call the class from WPF .NET using managed C# code:
Int32 a = 0;
  IntPtr pMyClass = MyClassHandling.Create();
            Int64 b = 0;
            long c = 0;
            long rslt = 0;

            try
            {
                MyClassHandling.SetFoo_1(pMyClass);


                if (Environment.Is64BitOperatingSystem)
                {
                    //"SysWOW64"
                    b = MyClassHandling.GetEAX(pMyClass);                   
...
                }
                else
                {
                    //"system32"
                    a = pMyClassHandling.GetEAX(pGraphics);
...
                }

MyClassHandling.Dispose (pGraphics);
pMyClass = IntPtr.Zero;

Hi Jovanna,

attach your project to the topic .. welcome to the forum!  :P

Jovanna

Hi Masters, again!
Here is my repo, I've just published it. It is quite nice opportunity to combine Assembler with C++ with C# , but if the app runs... (Solution in VS2017  WPF app ( .NET Framework), added project: Visual C++ -> Windows Desktop -> Windows Desktop Wizard -> dll)
https://github.com/VanyaBenovska/Assembler_toCpp_toCs

...may be some VS settings in addition I need?

The ERROR: System.DllNotFoundException: 'Unable to load DLL 'SomeAssemblerFunctions.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)'
This is the error that I have to Assembly functions. I had also some C# functions, but they are not important, they run successfully and I deleted from project; My goal is to find why Assembler functions don't run..
Thanks in advance and
Nice day to all!!!

LiaoMi

Hi Jovanna,

I thought you would add a solution for the visual studio, some files are missing .. App.xaml, App.xaml.cs, App.config.

You can see the project ..Mixing .NET and Assembly Language in a standalone 64-bit exe, the implementation is different, but also interesting.
Mixing .NET and Assembly Language in a standalone 64-bit exe
https://www.codeproject.com/Articles/266717/Mixing-Net-and-Assembly-Language-in-a-standalone-6

FAQ
Q: Any sample for mixing .NET and Assembly Language in a standalone 32-bit exe?
A: The same sample, but for 32-bit, is in my website at: http://www.atelierweb.com/articles/NetAndAsm32.htm

The author is on the forum, you can ask questions ...

Jovanna

Hi LiaoMi,
thanks for the answer, I tryed to send all VS files zipped in attachment but the size is not allowed, so I devided them in 2 parts and published again in my GitHub:
CsAssemblerVisualizer_Part_1.zip, and CsAssemblerVisualizer_Part_2.zip
https://github.com/VanyaBenovska/Assembler_toCpp_toCs

.. may be some VS settings needed, I wonder

Nice day!!
Vanya

LiaoMi

Quote from: Jovanna on May 14, 2019, 07:55:20 PM
Hi LiaoMi,
thanks for the answer, I tryed to send all VS files zipped in attachment but the size is not allowed, so I devided them in 2 parts and published again in my GitHub:
CsAssemblerVisualizer_Part_1.zip, and CsAssemblerVisualizer_Part_2.zip
https://github.com/VanyaBenovska/Assembler_toCpp_toCs

.. may be some VS settings needed, I wonder

Nice day!!
Vanya

Thanks! You have a very unusual code, some functions are simply not there .. I would try to simplify the code and make a new example with one function.

A WPF GUI FOR A C++ DLL: A COMPLEX PINVOKE CONSTRUCT Link.txt - Sample source code can be downloaded below ... The difference between c ++ and assembler functions is small, there is no inline code in the 64 bit version, in 64-bit release you should create a separate file with assembler listing ..

jj2007

https://thebyte@@@@@.com/2014/07/31/a-wpf-gui-for-a-c-dll-a-complex-pinvoke-construct-2/

The Forum doesn't like the word "cuisine". Replace the @ with the English equivalent of "cuisine", and it will work.

Jovanna

Hi LiaoMi again,
thanks for answer. Meanwhile I found some errors, corrected them and the program is running, but only without Assembly function: goes in exception. Have you got any ideas?
Here is new version:
https://github.com/VanyaBenovska/Assembler_toCpp_toCs
CsAssemblerVisualizer_Part_1_ver.2.zip
and
CsAssemblerVisualizer_Part_2_ver.2.zip

Cheers!

Jovanna

Hi jj2007,
Thanks for the answer and I am really curious to see the code but I can't open.. tried several translations, just become hungry :-) (joke)
Greetings!

jj2007

Replace the @@@ in the URL with k_i_t_c_h_e_n without the "_" :P

LiaoMi

Quote from: Jovanna on May 15, 2019, 11:03:18 PM
Hi LiaoMi again,
thanks for answer. Meanwhile I found some errors, corrected them and the program is running, but only without Assembly function: goes in exception. Have you got any ideas?
Here is new version:
https://github.com/VanyaBenovska/Assembler_toCpp_toCs
CsAssemblerVisualizer_Part_1_ver.2.zip
and
CsAssemblerVisualizer_Part_2_ver.2.zip

Cheers!

Hi Jovanna,

my dll works fine, in my opinion, yours should work just like mine, but you have an error in the code where the result is processed ...

I commented out the last line and everything started to work. For debugging, I added a messagebox in dll
void MyClass::SetFoo_1()
{
resultEAX = new int;

try
{
int a = Foo_1();

wchar_t buffer[256];
wsprintfW(buffer, L"%d", a);
MessageBoxW(nullptr, buffer, buffer, MB_OK);

if (a == 1)
{
*resultEAX = 1;
}
}
catch (int e)
{
*resultEAX = 0;
}
}

int MyClass::GetEAX() {

wchar_t buffer[256];
wsprintfW(buffer, L"%d", *resultEAX);
MessageBoxW(nullptr, buffer, buffer, MB_OK);
return *resultEAX;
}


launched debugging in visual studio and noticed that the result changes twice =)

This style is very bad, the record is short, but it complicates reading the source code .. It is important to know, but it is better not to write like that.
(a == 1) ? (0).ToString() : (0).ToString();

Jovanna

Dear Friends, dear Assembler Masters,
first I apologize for haven't written so long. During this time I generated a lot of solutions of the problem but still don't have an app working properly on a virtual machine.
A very important: I blamed assembler, but it is not the problem of the app. (I generated versions including simple int-returning-functions, with no Assembler in it), and the problem stays.
Have written to Microsoft, here is the link:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e2c3ae8-3365-4f92-b63d-01d1193ef382/why-my-32-bit-wpf-net-app-cant-find-32-bit-dll?forum=csharpgeneral#1e2c3ae8-3365-4f92-b63d-01d1193ef382
Tryed to find the problem with Dependency Walker and the error is: ERROR: No DOS or PE signature found. This file is not a valid 32-bit or 64-bit Windows module.

Interesting, but one of my versions is working properly: but I did the dll on Code::Blocks. This version (only) is working correctly on a virtual machine, without "hanging". And another interesting situation: for curiosity I added this working CodeBlocks-version in Dependency Walker and there is The Same Error!
Incredible.
Really don't have any more ideas about the problem, how to solve...
Please help.
Kind regards and nice day,
Vanya

TimoVJL

Not an expert, but a small test
using System;
using System.Runtime.InteropServices;
// C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /platform:x86 MyClassDllTest.cs

  public static class ClassFromDllWithSomeAssemblerFunctions
  {
    [DllImport("MyClass.dll", CallingConvention = CallingConvention.StdCall)]
    static public extern IntPtr Create();

    [DllImport("MyClass.dll", CallingConvention = CallingConvention.StdCall)]
    static public extern int GetEAX(IntPtr pGraphicsObject);
  }

  class HelloCS
  {
    static void Main()
    {
      IntPtr p1_MyClass = ClassFromDllWithSomeAssemblerFunctions.Create();
      long rslt = ClassFromDllWithSomeAssemblerFunctions.GetEAX(p1_MyClass);
      Console.WriteLine("rslt:{0}", rslt);
    }
  }
May the source be with you

Jovanna

Hi TimoVJL,
no, it didn't run. Same ERROR: "Unhandled exception: "Unable to load DLL...."
.net Console, (both versions same result: bruild for Any CPU and build for x86):
using System;
using System.Runtime.InteropServices;

public static class ClassFromDllWithSomeAssemblerFunctions
{
    [DllImport("PInvoke_Class_Core_Win32DesktopDLL.dll", CallingConvention = CallingConvention.StdCall)]
    static public extern IntPtr Create();

    [DllImport("PInvoke_Class_Core_Win32DesktopDLL.dll", CallingConvention = CallingConvention.StdCall)]
    static public extern int GetEAX(IntPtr pGraphicsObject);
}

class Program
{
    static void Main(string[] args)
    {
        IntPtr p1_MyClass = ClassFromDllWithSomeAssemblerFunctions.Create();
        long rslt = ClassFromDllWithSomeAssemblerFunctions.GetEAX(p1_MyClass);
        Console.WriteLine("rslt:{0}", rslt);
    }
}

//Output:
//rslt:0   Only on my PC; when run exe+dll on a virtual machine - not able to find dll.

dll: Win32 DLL Desktp Project , target platform: x86:
MyCoreClass.h
#ifndef MYCLASS_H
#define MYCLASS_H

class __declspec(dllexport) MyClass
{
public:   
   int resultEAX ;

   int Foo_1();
   int Foo_2();
   void SetFoo_1();
   void SetFoo_2();
   int  GetEAX();
};
#endif

MyCoreClassCaller.h
#pragma once
#include "MyCoreClass.h"     

#ifdef __cplusplus

extern "C" {
#endif

    __declspec(dllexport) MyClass* Create();
    __declspec(dllexport) void Dispose(MyClass* a_pObject);
    __declspec(dllexport) void SetFoo_1(MyClass* a_pObject);
    __declspec(dllexport) void SetFoo_2(MyClass* a_pObject);
    __declspec(dllexport) int GetEAX(MyClass* a_pObject);

#ifdef __cplusplus
}
#endif

MyCoreClass.cpp
#include "stdafx.h"
//#include <Windows.h>

#include "MyCoreClass.h"


int MyClass::Foo_1()
{
   __asm
   {
      mov eax, 9
   }
}

int MyClass::Foo_2()
{
   __asm
   {
      mov eax, 8
   }
}

void MyClass::SetFoo_1()
{
   try
   {      
      this->resultEAX = Foo_1();
   }
   catch (int e)
   {
      this->resultEAX = 0;
   }
}

void MyClass::SetFoo_2()
{
   try
   {
      this->resultEAX = Foo_2();      
   }
   catch (int e)
   {
      this->resultEAX = 3;
   }
}

int MyClass::GetEAX()
{
   return this->resultEAX;
}


MyCoreClassCaller.cpp
#include "stdafx.h"
//#include <Windows.h>

#include "MyCoreClassCaller.h"

MyClass* Create()
{
   return new MyClass();
}

void Dispose(MyClass* a_pObject)
{
   if (a_pObject != 0)
   {
      delete a_pObject;
      a_pObject = 0;
   }
}

void SetFoo_1(MyClass* a_pObject)
{
   if (a_pObject != nullptr)
   {
      a_pObject->SetFoo_1();      
   }
}

void SetFoo_2(MyClass* a_pObject)
{
   if (a_pObject != nullptr)
   {
      a_pObject->SetFoo_2();
   }
}
int GetEAX(MyClass* a_pObject)
{
   if (a_pObject != 0)
   {
      return a_pObject->GetEAX();
   }
   return 0;
}

This is.
Kind regards




TimoVJL

#14
What is that virtual machine and what Microsoft.Net Framework versions it have ?
If the example can't find dll in same folder, it will be a bit strange thing.

The calling program needs that /platform:x86 as dll is x86 version.

BTW: please format with a code tags #

EDIT: My example was compiled with msvc 2013, so Vista (6.0) was target OS.
EDIT: msvc 2010 version, tested in Windows XP. After passing this test, is time to check msvc 2017 issues, like target to v140_xp, if necessary.


May the source be with you