簡體   English   中英

無法在 Dll 主 C++/CLI 中發送任何 web 請求

[英]Cant send any web request in Dll main C++/CLI

我想在 c++/cli 中向 url 發送一個簡單的獲取請求,但我無法得到任何響應! 我通過 (WebClient) 或 (HttpWebRequest) 執行此操作,但無法獲得任何結果! 我檢查了代碼,發現代碼停留在 DownloadString(在 webclient 中)

順便說一句,我在 c++/cli 控制台應用程序中測試了這個確切的代碼,並且工作起來非常棒! 但我無法在 c++/cli ClassLibrary 項目中得到任何結果

這是我的代碼:

System::String^ addr = "https://google.com";
System::Net::WebClient^ wc = gcnew System::Net::WebClient();
System::String^ data = wc->DownloadString(addr);
System::IO::File::WriteAllText("Data.txt", data->ToString());

通過DllMain調用以上代碼:

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        
    }
    case DLL_THREAD_ATTACH:
    {
    }
    case DLL_THREAD_DETACH:
    {
    }
    case DLL_PROCESS_DETACH:
    {
    }
    break;
    }
     CallWebClient();
    while (true)
    {

    }

    return TRUE;
}

這是一個使用全局同步事件的示例。

有兩個項目:ClrDll 和 ClrApp。 ClrDll 中的 DllMain 只是觸發事件。 ClrApp 被動地等待這個事件,當它到達時,開始新的下載。

筆記:

  • dllmain.cpp 不得包含任何托管代碼!
  • 您必須刪除 dllmain.cpp 屬性中的 /clr 選項(C/C++/General/Common Language RunTime Support)!
  • 您可能需要在 dllmain.cpp 屬性 (C/C++/Precompiled Headers/ Precompiled Header) 中禁用預編譯標頭的使用!

由於您沒有提供足夠的信息,您的目標可能會以不同且更簡單的方式實現。

僅當您可以在主應用程序(而不是 dll 本身)中設置監聽事件時,此解決方案才有意義。

dllmain.cpp:

#include <windows.h>

HANDLE hEvent = NULL;

void FireEvent()
{
    if (hEvent == NULL)
        hEvent = CreateEventA(NULL, FALSE, FALSE, "ClrDll_DllMain");

    SetEvent(hEvent);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    FireEvent();

    return TRUE;
}

應用程序.cpp:

#include "pch.h"
using namespace System;
using namespace System::IO;
using namespace System::Net;
using namespace System::Threading;

ref class Watcher
{
private: Thread^ thread;
private: AutoResetEvent^ cancel = gcnew AutoResetEvent(false);
private: EventWaitHandle^ dllmain = gcnew EventWaitHandle(false, EventResetMode::AutoReset, "ClrDll_DllMain");

public: void Start() {

    if (thread == __nullptr) {
        thread = gcnew Thread(gcnew ThreadStart(this, &Watcher::Work));
        thread->Start();
    }
}

public: void Stop() {
    if (thread != __nullptr) {
        cancel->Set();
        thread->Join();
        thread = __nullptr;
    }
}

public: void Work() {
    array<WaitHandle^>^ events = gcnew array<WaitHandle^>(2);
    events[0] = cancel;
    events[1] = dllmain;

    while (true) {
        int index = WaitHandle::WaitAny(events);
        if (index == 0)
            return;

        if (index == 1)
            OnDllMain();
    }
}

protected: void OnDllMain()
{
    String^ addr = "https://google.com";
    WebClient^ wc = gcnew WebClient();
    String^ data = wc->DownloadString(addr);
    File::WriteAllText("Data-" + DateTime::UtcNow.Ticks.ToString() + ".txt", data->ToString());
}

};

int main(array<System::String ^> ^args)
{
    Watcher^ watcher = gcnew Watcher();
    watcher->Start();

    ClrDll::Class1^ o = gcnew ClrDll::Class1();
    Thread::Sleep(5000);

    watcher->Stop();

    return 0;
}

ClrDll.h

#pragma once

using namespace System;

namespace ClrDll
{
    public ref class Class1 {
    public: Class1() {
            System::Diagnostics::Debug::WriteLine("Class1 ctor");
    }
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM