0

I imported a DLL that I compiled with rato.hpp:

#ifndef RATO_H
#define RATO_H

extern "C"
{
    __declspec(dllexport) void mouse_move(char button, char x, char y, char wheel);
}
#endif

and rato.cpp:

typedef struct {
        char button;
        char x;
        char y;
        char wheel;
        char unk1;
    } MOUSE_IO;

void mouse_move(char button, char x, char y, char wheel)
    {
        MOUSE_IO io;
        io.unk1 = 0;
        io.button = button;
        io.x = x;
        io.y = y;
        io.wheel = wheel;

        if (!callmouse(&io)) {
            mouse_close();
            mouse_open();
        }
    }

When importing it in my CSharp code, I can't cast negative values:

[DllImport("Rato.dll")]
public static extern void mouse_move(char button, char x, char y, char wheel);

mouse_move((char)0,(char)0,(char)-150,0);

I tried to convert, but it doesn't work, it keeps sending positive values instead of negative.

EDIT: Tried to convert to sbyte but get error

System.OverflowException: 'Value was either too large or too small for a signed byte.'

[DllImport("Rato.dll")]
public static extern void mouse_move(sbyte button, sbyte x, sbyte y, sbyte wheel);

mouse_move(0,0,Convert.ToSByte(-150),0);

How can I sucessfully pass negative char value to C imported DLL?

phuclv
  • 37,963
  • 15
  • 156
  • 475
juauzynhu
  • 3
  • 2
  • Did you try to use `signed char` explicitly? A `char` has no default signedness. – the busybee Jun 20 '22 at 13:22
  • 3
    `char` in C# isn't a numeric type, it represents a character encoded in Unicode UTF-16. C's char is equivalent to C#'s [`byte`](https://learn.microsoft.com/en-us/dotnet/api/system.byte?view=net-6.0) or [`sbyte`](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte?view=net-6.0) depending on whether or not your C `char` contains negative numbers or not. In your case, you should use `sbyte` – MindSwipe Jun 20 '22 at 13:23
  • I tryied "[DllImport("Rato.dll")] public static extern void mouse_move(sbyte button, sbyte x, sbyte y, sbyte wheel);" but it keeps casting positive (moving mouse to right, not left) – juauzynhu Jun 20 '22 at 13:25
  • The smallest possible value of an `sbyte` (and also a `signed char` in C on most platforms) is -128. So what are you trying to achieve by sending `-150`? – UnholySheep Jun 20 '22 at 13:30
  • Also you need `CallingConvention = CallingConvention.CDecl` in your `DllImport` attribute – Charlieface Jun 20 '22 at 13:49

1 Answers1

1

char in C# is a 16-bit unsigned type so obviously you can't use it to interop with char in C++. sbyte is the way to go. However the range of sbyte is -128 to 127, similar to unsigned char in C when CHAR_BIT == 8, so obviously -150 can't fit in C# sbyte/C char

Note: char in C can be signed or unsigned, so if for example you use the /J option in MSVC or the -funsigned-char option in GCC in your project then you can't pass a negative value to the C function

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • What I need to use to achieve higher ranges? – juauzynhu Jun 20 '22 at 13:36
  • 2
    obviously by changing your C++ code (not C, the extension is cpp) to use a wider type like `short` or `int`. Most of the time `int` would be recommended. Why don't just check your C++ book? – phuclv Jun 20 '22 at 13:39