'laguage'에 해당되는 글 2건

  1. 2015.01.28 파일변경시 node 자동으로 재시작 모듈
  2. 2014.02.06 C#에서 C++ DLL 사용하기
laguage/nodejs2015. 1. 28. 10:43

 node.js로 백엔드를 구축하려 하는데 개발환경을 어떤식으로 구축하려 생각하다.. 

 개발한 내용을 저장하면 재시작 해주는게 없나... 구글링 했더니. 역쉬.. 있다..


 간단히 찾은 것이 supervisor 라는 모듈과 nodemon 이놈들 중 어떤 것이 더 버그없고 활용도가 좋은지는 모르겠으나..

 그냥 둘 다 써보자라는 생각으로.. 노트 해 둔다..


 사용법은 아래와 같다.

 

 supervisor 

 설치 : npm install -g supervisor

 supervisor app.js


 

 아.. 그리고 배포 후 운영시.. 어떤 에러로 프로세서가 종료 될때. forever라는 모듈을 이용하면, 다시 재시작 시켜준다.

 forever는 npm에서 전역으로 설치해놓고 사용하면 좋을것 같다



 forever 

 설치 : npm install -g forever

 실행 : forever app.js

 실행중인 리스트 : forever list

 정지 : forever stop 0  



Posted by cz
laguage/c#2014. 2. 6. 23:47

C#에서 C++ DLL 사용하기

개요

C#에서 C++ dll을 사용하기 위해서는 pinvoke(platform invoke)를 사용하면 된다. 아래의 내용은 사용법에 대한 간단한 정리이다. 내용 생략하고 Sample 를 받아도 된다.

C++

h

// Ŭnicode please
#pragma once

#include <cstdio>

namespace ns {;
typedef struct tTest {
    char  strTest[128]; //문자열 128
    int   intTest;    //숫자형
    char byteTest[64]; //바이트형 배열
    unsigned int  uintTest[4];  //유니트형 배열

} typeTest;
}

extern "C" __declspec(dllexport) void   OnTest1(void);      //기본형
extern "C" __declspec(dllexport) int    intOnTest2(int intTemp);    //입출력 숫자형
extern "C" __declspec(dllexport) int*  strOnTest3();  //입출력 문자열형
extern "C" __declspec(dllexport) void   OnTest4(ns::typeTest *testTemp);    //입력 구조체(포인터 출력가능)
extern "C" __declspec(dllexport) void   OnTest5(int *intTemp);  //입출력 배열(포인터 출력가능)
  • 문자열을 반환하는 경우 char포인터를 리턴하는 대신 int*를 리턴하고 C#쪽에서 적절히 캐스팅해서 받아야한다
  • C#쪽에서 구조체를 구성하는것은 메모리 구조만 맞추면 되니까 네임스페이스건 뭐건 잇건 없건 큰 문제가 없다
  • dll 인터페이스로 만들기 위해서 extern "C" __declspec(dllexport)를 함수에 넣어준다

cpp

// Ŭnicode please
#include "sample.h"

void OnTest1(void)
{
    //기본형
  printf("fdsfd\n");
}

int intOnTest2( int intA)
{
    //입출력 숫자형

    ++intA; //입력받은 숫자에 +1

    return intA;
}

int* strOnTest3()
{
    //입출력 문자열형

    //static char strTemp2[128] = {0,};   //임시저장용 문자열
    //sprintf_s( strTemp2, "%s strOnTest3 에서 리턴", strTemp);   //문자열 합치기
    static char strTemp2[256] = "asdfasds\n";
    return (int*)strTemp2;
}

void OnTest4( ns::typeTest *testTemp )
{
    //입력 구조체형(포인터 출력가능)

    testTemp->byteTest[0] = 1;
    testTemp->intTest = testTemp->intTest + 2;
    sprintf_s( testTemp->strTest, "%s OnTest4에서 포인터", testTemp->strTest);
    testTemp->uintTest[0] = 1;
}

void OnTest5(int *intTemp)
{
    //입출력 배열형(포인터 출력 가능)
    for( int i = 0 ; i < 2 ; ++i )
    {
        intTemp[i] = intTemp[i] + i;
    }
}

C#

구조체

public struct typeTest
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public String strTest;

    public int intTest;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
    public byte[] byteTest;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public UInt32[] uintTest;
}

함수

[DllImport("dll_sample.dll")]
extern public static void OnTest1();

[DllImport("dll_sample.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static int intOnTest2(int intTemp);

[DllImport("dll_sample.dll", CharSet = CharSet.Ansi)]
extern public static IntPtr strOnTest3();

[DllImport("dll_sample.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static void OnTest4(ref typeTest testTemp);

[DllImport("dll_sample.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static void OnTest5(int[] intTemp);
private void button1_Click(object sender, RoutedEventArgs e)
{
    OnTest1();
}

private void button2_Click(object sender, RoutedEventArgs e)
{
    int a = 1;
    a = intOnTest2(a);
    System.Console.WriteLine(a);
}

private void button3_Click(object sender, RoutedEventArgs e)
{
    IntPtr a = strOnTest3();
    string s = Marshal.PtrToStringAnsi(a);
    System.Console.WriteLine(s);
}

private void button4_Click(object sender, RoutedEventArgs e)
{
    typeTest testTemp = new typeTest();

    testTemp.byteTest = new byte[64];
    testTemp.uintTest = new uint[4];

    testTemp.strTest = "asd";
    testTemp.intTest = 3;
    testTemp.byteTest[0] = (byte)'a';
    testTemp.uintTest[0] = 12;


    OnTest4(ref testTemp);

    System.Console.WriteLine(testTemp);
}

private void button5_Click(object sender, RoutedEventArgs e)
{
    int[] intTemp = new int[2];
    intTemp[0] = 1;
    intTemp[1] = 2;
    OnTest5(intTemp);
    System.Console.WriteLine(intTemp);
}
  • 함수호출할때 인자를 사용하는 경우, CallingConvention = CallingConvention.Cdecl 가 필요하다
  • C++에서 char포인터를 반환하는 경우, C#에서의 type은 IntPtr이다. Marshal.PtrToStringAnsi 를 사용해서 string으로 바꿀수잇다. string으로 바로 받으면 에러가 발생한다

Reference


Posted by cz