小编UnT*_*aDe的帖子

C++继承函数覆盖

我是C++的新手,我来自Java/C#.

我知道在Java和C#中你可以创建一个类,让另一个类继承它,并覆盖它的功能.然后,您可以创建父类的列表,并将子类的对象插入此列表中.之后,您可以使用被覆盖的功能.

例:

public class Parent
{
  public virtual void test()
  {
    Console.WriteLine("test");
  }
}

public class Child : Parent
{
  public override void test()
  {
    Console.WriteLine("test2");
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

List<Parent> tests = new List<Parent>();
tests.Add(new Child());
tests[0].test();
Run Code Online (Sandbox Code Playgroud)

输出:

test2
Run Code Online (Sandbox Code Playgroud)

在C++中,当我这样做时std::vector,它调用父的成员函数,而不是子函数.

如何在C++中完成上述操作?

c++

3
推荐指数
1
解决办法
3787
查看次数

带指针的C ++类型转换

我来自C#和Java的背景,我似乎无法理解C ++中使用指针进行强制转换的含义。

例如:

int x = 1;
char c = *((char*)&x);
Run Code Online (Sandbox Code Playgroud)

它有什么作用?它有什么用?

c++ pointers casting

3
推荐指数
1
解决办法
2万
查看次数

C++ Winsock 10093错误

我正在尝试用C++构建一个可以接受多个客户端的服务器.为此,我构建了一个winsock包装器,并为每个客户端使用带有boost的线程进行通信.
我在尝试接受客户端时遇到了一个奇怪的问题,我有一个看起来像这样的循环.

int clientID = 0;
listenSocket = new Socket(SocketType::TCP);
listenSocket->Bind(port);
listenSocket->Listen();

while(running)
{
    Socket *socket = &listenSocket->Accept();
    mutex.lock();
    clients.push_back(new Client(socket,  clientID));
    mutex.unlock();

    std::cout << "Client with id " << clientID << " connected!" << std::endl;

    std::cout << WSAGetLastError() << std::endl;

    clientID++;
}
Run Code Online (Sandbox Code Playgroud)

现在,第一个客户端接受罚款并且WSAGetLastError()返回0,但是在第一个连接后,即使我不尝试连接另一个,它只是继续写入控制台10093,这意味着循环中的Accept()停止阻塞由于某种原因不能正确接受.我在网上看到这个错误是由于没有调用WSAStartup()引起的,但是我确实在socket的构造函数中调用了它,并且它在第一次接受了它.

c++ winsock

2
推荐指数
2
解决办法
2万
查看次数

消息模式下的 C# 命名管道有时会合并消息?

我在我正在处理的项目中使用命名管道,双方都是用 C# 编写的(客户端和服务器),并且都在同一台计算机上(命名管道用于 RPC)。两侧的命名管道设置为使用“PipeTransmissionMode.Message”模式,根据我的理解,该模式应该将传递给 pipe.Write() 的每个数据块“打包”在一条消息中,并将 pipe.Read() 放在另一端应该接收整个消息或不接收任何消息。

在尝试对接收端的数据进行反序列化时,我看到我得到了大量数据,比我发送的数据包还要大。于是我做了一个小测试,我创建了两个Application,server和client,看起来是这样的:

服务器:

class Program
{
    static void Main(string[] args)
    {
        NamedPipeServerStream pipe = new NamedPipeServerStream("TestPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024);
        pipe.WaitForConnection();

        Random random = new Random();

        while(true)
        {
            byte[] buffer = new byte[32];
            random.NextBytes(buffer);
            pipe.Write(buffer, 0, buffer.Length);
            Console.WriteLine(buffer.Length);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

客户:

class Program
{
    static void Main(string[] args)
    {
        NamedPipeClientStream pipe = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut, PipeOptions.Asynchronous);
        pipe.Connect();

        while(true)
        {
            byte[] buffer = new byte[2048];
            int read = pipe.Read(buffer, 0, …
Run Code Online (Sandbox Code Playgroud)

c# rpc ipc named-pipes

2
推荐指数
1
解决办法
3869
查看次数

在C中声明堆栈上的数组(VS2015)

当我尝试在C中声明堆栈上的数组时,我遇到了一个奇怪的问题.我一直认为(至少到现在为止)如果没有常量表达式就不可能在堆栈上声明数组.例如,尝试在Windows上的VS2015上编译以下代码:

int main()
{
    int i = 3;
    int test[i];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产生"表达式必须具有常量值"错误,这是我所期望的,但是在Linux机器上使用gcc和clang编译相同的代码是有效的.起初我以为这可能是编译器推断的东西,所以我尝试了以下内容:

int main()
{
    int i = 3;
    int j = i*i;
    int test[j];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

VS2015再次抱怨同样的错误,但是gcc和clang编译得很好!我立即想,好吧也许这些编译器也在推断它,毕竟它只是"不变"的表达式.所以我尝试了以下方法:

int main()
{
    int i = getchar();
    int test[i];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然编译器无法推断这一点,i用于声明的test值只能在运行时知道,但令我惊讶的是,VS2015再次抱怨,但是gcc和clang编译了它......甚至添加了以下内容:

int main()
{
    int i = getchar();
    int test[i];

    printf("%d\n", sizeof(test) / sizeof(int));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

x在ASCII表中输入其值为120的字符,输出120.

这是怎么回事?

c arrays gcc clang visual-studio

2
推荐指数
1
解决办法
123
查看次数

用C++表示简单的汇编代码,而不是函数

我正在尝试为某些win32 api函数编写一个trampoline挂钩,当我将JMP指令写入原始函数的开头时,我希望它跳转到codecave而不是调用函数.

OllyDBG中的原始函数start如下所示:

PUSH 14
MOV EAX, 12345678
...
Run Code Online (Sandbox Code Playgroud)

我将其修补为:

JMP 87654321
NOP
NOP
Run Code Online (Sandbox Code Playgroud)

以下功能的地址:

int HookFunc(int param)
{
    DoStuff(param);
    return ExecuteOriginal(param);
}
Run Code Online (Sandbox Code Playgroud)

ExceuteOriginal看起来像这样:

unsigned long address = AddressOfOriginalFunction + 7;

int ExceuteOriginal(int param)
{
    __asm
    {
        PUSH 0x14
        MOV EAX, 0x12345678
        JMP address
    }
}
Run Code Online (Sandbox Code Playgroud)

执行被覆盖的代码并在修补后的代码后立即跳转到原始函数.问题在于,由于它是一个函数,它会使堆栈陷入困境,因为调用者应该清理它并且函数而不是返回,跳转到另一个函数的代码.我猜这就是程序崩溃的原因.

有没有办法使用Visual C++编译器将汇编代码放在程序的代码部分而不是在函数内部?这样我就可以跳到那里,执行任何操作,然后返回,而不会有弄乱堆栈的风险.

c++ hook inline-assembly

0
推荐指数
1
解决办法
847
查看次数

Roslyn是一个完整的编译器吗?

Roslyn是一个完整的独立C#编译器吗?我看了一下源代码,似乎它使用了Visual Studio中的编译器,我也没有在它的GitHub存储库(https://github.com/dotnet/roslyn)中找到任何源代码与解析有关.

c# compiler-construction roslyn

0
推荐指数
1
解决办法
691
查看次数