ブログ

割とコンピュータよりの情報をお届けします。

2018/8/16

C++のauto C#のvar

C++11からはC++でもC#のvarのように変数宣言時に具体的な型名を記述せずにautoキーワードで代用することが可能になっている。

autoキーワードを使用する場合にもコンパイルして実行する段階では変数型は指定される必要がある。

コードを使いまわす際にいちいち変数型を切り替えて書き直すという手間を軽減することができるようになった。

#include "stdafx.h"


int main()
{
auto a = 10;
_tprintf_s(_T("%d %d\n"), a);
    return 0;
}

でもよく,C/C++っていうのでC言語とC++言語は混ざることがあるのでC言語の仕様をよく知っている人には混乱するかもしれない。
今更このように書く人はいないが,
auto int b = 10;
などはつかえない。

ところが,cppファイルの拡張子をcppからcに変更するとVisual C++でも以下のような使い方ができるようになる。(autoがどっちの意味でも通るようになる)

int main()
{
auto a = 10;
auto int b = 10;
_tprintf_s(_T("%d %d\n"), a, b);
return 0;
}

意味を理解せずに使うのは注意。。

≫ Read More

2018/08/16 コンピュータ   TakeMe

Windowsで共有メモリの使用WindowsサービスとWindowsアプリケーション間のやり取り

WindowsでWindowsサービスとアプリケーションの間の共有メモリによるデータのやり取りを確認していた。

まずは簡単に,共有メモリの使い方を学習する。
参考にするページはこのページ
とりあえず,CreateFileMappingとMapViewOfFileを使用することでメモリの共有ができる。しかし,これができるのは同じユーザの場合。
Windowsサービスとユーザアプリケーション間のやり取りに苦労する。

そこで次の例を読み込む。
CreateFileMappingの2つ目の引数をNULLではなく設定するのだ。

ここまでできるとサービス側で読み書きできて,アプリケーション側では読み取り専用で開かせたい。

アプリケーション側

#include "stdafx.h"

int main()
{
    TCHAR name[] = _T("Global\\somename");
    DWORD dwSize = sizeof(int);

    HANDLE hSharedMemory = OpenFileMapping(
        FILE_MAP_READ,//FILE_MAP_ALL_ACCESS,
        FALSE,
        name
    );
    int* pMemory = (int*)MapViewOfFile(hSharedMemory, FILE_MAP_READ/*FILE_MAP_ALL_ACCESS*/, NULL, NULL, dwSize);

    for (int i = 0; i < 40; i++)
    {
        //(*pMemory)--;
        _tprintf_s(_T("memory: %d\n"), *pMemory);
        Sleep(500);
    }

    UnmapViewOfFile(pMemory);
    CloseHandle(hSharedMemory);

    return 0;
}

 

サービス側 試行錯誤してみました。

#include "stdafx.h"


int main()
{
    TCHAR name[] = _T("Global\\somename");
    DWORD dwSize = sizeof(int);

    SECURITY_DESCRIPTOR secDesc;
    SECURITY_ATTRIBUTES secAttr;
    InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION);

    DWORD dwAclSize = 1024;
    SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_LOCAL_SID_AUTHORITY; // SECURITY_WORLD_SID_AUTHORITY (Everyone)でもよい
    PSID pSid = NULL;
    if (!AllocateAndInitializeSid(&SIDAuth, 1,
        SECURITY_WORLD_RID,
        0, 0, 0, 0, 0, 0, 0,
        &pSid))
    {
        return 1;
    }
    PACL pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
    if (pDacl == NULL) {
        return 1;
    }

    // 随意アクセス制御リストを初期化
    InitializeAcl(pDacl, dwAclSize, ACL_REVISION);

    // ACE(アクセス制御エントリ)をDACLに追加
    AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_READ, pSid);
    AddAccessDeniedAce(pDacl, ACL_REVISION, GENERIC_WRITE, pSid);

    SetSecurityDescriptorDacl(&secDesc, TRUE, pDacl, FALSE);
    
    secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    secAttr.bInheritHandle = TRUE;
    secAttr.lpSecurityDescriptor = &secDesc;

    HANDLE hSharedMemory = CreateFileMapping(INVALID_HANDLE_VALUE, &secAttr, PAGE_READWRITE, NULL, dwSize, name);

    LocalFree(pDacl);
    FreeSid(pSid);

    int* pMemory = (int*)MapViewOfFile(hSharedMemory, FILE_MAP_ALL_ACCESS, NULL, NULL, dwSize);

    *pMemory = 0; // Only the administrators process can handle it as fully accessible variable.
    for (int i = 0; i < 40; i++)
    {
        (*pMemory)++;
        _tprintf_s(_T("src_memory: %d\n"), *pMemory);
        Sleep(1000);
    }

    UnmapViewOfFile(pMemory);
    CloseHandle(hSharedMemory);
    return 0;
}

特に
AddAccessAllowedAce(pDacl, ACL_REVISION, GENERIC_READ, pSid);
AddAccessDeniedAce(pDacl, ACL_REVISION, GENERIC_WRITE, pSid);
の周辺を入れていました。

[参考]

  1. C++で複数プロセスから読み書き可能な共有メモリを作る
  2. 【共有メモリ】アクセスが拒否されました。

≫ Read More

2018/08/16 コンピュータ   TakeMe