<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>투덜이의 리얼 블로그</title>
    <link>https://tourspace.tistory.com/</link>
    <description>일, 취미, 친구, 일상의 모든것들.</description>
    <language>ko</language>
    <pubDate>Wed, 6 May 2026 14:56:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>뚜덜이~</managingEditor>
    <image>
      <title>투덜이의 리얼 블로그</title>
      <url>https://t1.daumcdn.net/cfile/tistory/9937F73359B20DD32E</url>
      <link>https://tourspace.tistory.com</link>
    </image>
    <item>
      <title>[KMP] KMP 라이브러리를 Flutter에서 사용하기 - flutter plugin에서 dll load  #4</title>
      <link>https://tourspace.tistory.com/634</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEcNM5/btsL22J7tdv/tQcLNLYE4bsMOyisnT6Bak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEcNM5/btsL22J7tdv/tQcLNLYE4bsMOyisnT6Bak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEcNM5/btsL22J7tdv/tQcLNLYE4bsMOyisnT6Bak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEcNM5%2FbtsL22J7tdv%2FtQcLNLYE4bsMOyisnT6Bak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7781&quot; height=&quot;4377&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fultter에서 dll 파일을 로드하려면 두가지 방법이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 사용했던 &lt;span style=&quot;color: #ee2323;&quot;&gt;method channel&lt;/span&gt;을 사용하는 방법, &lt;span style=&quot;color: #ee2323;&quot;&gt;ffi plugin&lt;/span&gt;을 사용하는 방법인데, 전자의 경우 구현하기가 까다롭습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mac os에서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;method channel&lt;/span&gt;을 통하여 xcFramework의 함수를 호출하기 위해서 swift 코드에 호출할 함수를 맵핑시켜 주는 코드를 아주 조금만 수정하면 가능했으나, windows dll의 경우 C++ 언어로 이 작업을 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kmp 는 &lt;b&gt;kotlin&lt;/b&gt;으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mac용 flutter에 로드하기 위해서 &lt;b&gt;swift&lt;/b&gt;로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows용 flutter에 로드하기 위해서 &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;C++&lt;/span&gt;&lt;/b&gt;로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 OS에서 맵핑된 함수를 dart로 뽑아내기 위해서는 &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dart&lt;/span&gt;&lt;/b&gt;로..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 사용해야 하는 언어가 너무 많아지고 복잡해 지므로 여기서는 flutter plugin중 하나의 &lt;span style=&quot;color: #006dd7;&quot;&gt;ffi&lt;/span&gt;를 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;FFI 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flutter plugin의 &lt;span style=&quot;color: #ee2323;&quot;&gt;pubspec.yaml&lt;/span&gt;에 아래와 같이 ffi 를 추가합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737877451788&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...

dependencies:
  flutter:
    sdk: flutter
  ffi: ^2.1.3
  ...

...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성했던 dll 파일을 &lt;b&gt;plugin 프로젝트의 windows 폴더 아래 복사&lt;/b&gt;합니다. &lt;i&gt;단 주의할 점은 plugin 프로젝트에서 이를 실행시키이 위한 example/windows 폴더도 존재합니다.&lt;/i&gt; 여기에 복사하지 않됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &quot;프로젝트명/windows/MyLib.dll&quot;&lt;/b&gt;&amp;nbsp;의 경로에 복사되어야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Library Load&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리의 로드는 open 함수 바로 수행할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737878050643&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    DynamicLibrary dyLib = DynamicLibrary.open('../windows/MyLib.dll');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 library를 로드할때 singleton으로 만들어 한번만 로드하여 사용하도록 아래와 같이 만듭니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737877977561&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//load_libaray.dart

import 'dart:ffi';
import 'dart:io';

/// Library load를 처리
class LoadLibrary {
  LoadLibrary._privateConstructor();

  static final LoadLibrary _instance = LoadLibrary._privateConstructor();

  factory LoadLibrary() {
    return _instance;
  }

  DynamicLibrary? loadLib() {
    print(&quot;current Directory: ${Directory.current.path}&quot;);

    DynamicLibrary dyLib;

    try {
      if (Platform.isWindows) {
        dyLib = DynamicLibrary.open('../windows/MyLib.dll');
      } else {
        print(&quot;Not supported OS&quot;);
        return null;
      }
      print(&quot;load lib success&quot;);
    } catch (e) {
      print('F11ailed to load DLL: $e');
      return null;
    }

    return dyLib;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dll을 파일을 정확한 위치에 잘 복사했다면 load 성공 메시지를 확인할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Libarary 함수 호출&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 호출시 호출할 라이브러리 함수의 signature와 이를 maping할 dart 함수의 signature를 선언합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737878514056&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@OptIn(ExperimentalNativeApi::class)
@CName(&quot;inputTest&quot;)
fun inputTest(name: String): Int {
    println(&quot;inputTest() - name:$name&quot;)
    return 100
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 함수가 kmp로 선언했던 함수입니다. 이 함수가 dll로 컴파일되면 String같은 경우 char*로 변경되면서 pointer로 접근해야 합니다. (참고로 kmp 빌드시 dll과 함께 header파일이 같이 제공 됩니다. 실제로는 dll 파일만사용하지만 header 파일을 열어 extern c로 구성된 함수의 함수 signature를 확인할 수 있습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1737878754514&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;typedef InputTestNative = Int32 Function(Pointer&amp;lt;Utf8&amp;gt; name); //dll 함수 타입
typedef InputTestDart = int Function(Pointer&amp;lt;Utf8&amp;gt; name);     //dart 함수 타입&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 호출할때는 lookup 함수를&amp;nbsp; 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737879229933&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// library에서 inputTest() 함수 검색
final InputTestDart inputTest = dyLib
         .lookup&amp;lt;NativeFunction&amp;lt;InputTestNative&amp;gt;&amp;gt;(&quot;inputTest&quot;)
         .asFunction();

// 입력값 pointer로 변환
final paramPointer = &quot;홍길동&quot;.toNativeUtf8();

// 함수 호출
final int result = inputTest(paramPointer);

// param으로 만들었던 pointer 해제
calloc.free(paramPointer);

print('result: $result');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;param으로 넘겨야 하는 값이 &lt;span style=&quot;color: #ee2323;&quot;&gt;char*&lt;/span&gt; 이기 때문에 pointer를 만들어 담아서 dll 함수를호출하고, 사용 이후에 반드시 &lt;span style=&quot;color: #ee2323;&quot;&gt;free&lt;/span&gt;로 해제해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 전체 함수를 보면 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737879378507&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'dart:ffi';
import 'package:ffi/ffi.dart';
import '../load_library.dart';
import 'dart:io' show Directory, Platform;

typedef InputTestNative = Int32 Function(Pointer&amp;lt;Utf8&amp;gt; name); //dll 함수 타입
typedef InputTestDart = int Function(Pointer&amp;lt;Utf8&amp;gt; name);     //dart 함수 타입

class TestCall {
  static final TAG = 'TestCall';
  final loadedLibrary = LoadLibrary();
  final nativeFunctionName = 'inputTest';

  Future&amp;lt;String?&amp;gt; invoke() {
    print('current Directory: ${Directory.current.path}');
    print('requestTest: $requestTest');

    int? result;
    Pointer&amp;lt;Utf8&amp;gt;? paramPointer;
    try {
      // library 로드
      final dyLib = loadedLibrary.loadLib();
      if (dyLib != null) {
          // 함수 호출
          InputTestDart inputTest = dyLib
            .lookup&amp;lt;NativeFunction&amp;lt;InputTestNative&amp;gt;&amp;gt;(nativeFunctionName)
            .asFunction();

          // param 준비
          final paramPointer = &quot;내 이름은 홍길동&quot;.toNativeUtf8();
          result = inputTest(paramPointer);
          print('result: $result');
      }      
    } catch (e) {
      print('Failed to load DLL: $e');
    } finally {
      //dart에서 선언한 pointer는 dart에서 해제해야 한다.
      if (paramPointer != null) {
        calloc.free(paramPointer);
      }
    }
    return Future.value(result ?? &quot;Failed to call inputTest() Native function&quot;);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Pointer를 사용하는 추가 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1737879744939&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@OptIn(ExperimentalNativeApi::class)
@CName(&quot;returnParam&quot;)
fun returnParam(name: String): String {
    println(&quot;inputTest() - name:$name&quot;)
    return name
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위와 같이 String을 param으로 받고 String을 반환하는 함수라면 아래와 같이 선언하고 호출해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 코드&lt;/p&gt;
&lt;pre id=&quot;code_1737879835295&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;typedef ReturnParamNative = Pointer&amp;lt;Utf8&amp;gt; Function(Pointer&amp;lt;Utf8&amp;gt; name); //dll 함수 타입
typedef ReturnParamDart = Pointer&amp;lt;Utf8&amp;gt; Function(Pointer&amp;lt;Utf8&amp;gt; name);   //dart 함수 타입

// library에서 inputTest() 함수 검색
final ReturnParamDart inputTest = dyLib
         .lookup&amp;lt;NativeFunction&amp;lt;ReturnParamNative&amp;gt;&amp;gt;(&quot;returnParam&quot;)
         .asFunction();

// 입력값 pointer로 변환
final paramPointer = &quot;임꺽정&quot;.toNativeUtf8();

// 함수 호출
Pointer&amp;lt;Utf8&amp;gt;? name = inputTest(paramPointer);
String result = name.toDartString(); // dart string으로 변환

// param으로 만들었던 pointer 해제
calloc.free(paramPointer);

print('result: $result');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주위할 점은 함수의 return값이 pointer 이므로 이를 재변환하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;toDartString()&lt;/span&gt; 함수를 사용한다는점 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/Kotlin</category>
      <category>cname</category>
      <category>dll 로드</category>
      <category>dynamiclibrary</category>
      <category>ffi</category>
      <category>flutter plugin</category>
      <category>kmp dll build</category>
      <category>pointer</category>
      <category>todartstring()</category>
      <category>tonativeutf8</category>
      <category>windows flutter</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/634</guid>
      <comments>https://tourspace.tistory.com/634#entry634comment</comments>
      <pubDate>Sun, 26 Jan 2025 17:29:19 +0900</pubDate>
    </item>
    <item>
      <title>[KMP] KMP 라이브러리를 Flutter에서 사용하기 - Windows용 dll 빌드 #3</title>
      <link>https://tourspace.tistory.com/633</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nmxEu/btsL0ZBUgb6/L2bDBQkGFRCPffN8JfcqA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nmxEu/btsL0ZBUgb6/L2bDBQkGFRCPffN8JfcqA1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nmxEu/btsL0ZBUgb6/L2bDBQkGFRCPffN8JfcqA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnmxEu%2FbtsL0ZBUgb6%2FL2bDBQkGFRCPffN8JfcqA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7781&quot; height=&quot;4377&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 내용에서 kmp로 만든 코드를 macOS용 library를 만들고, 이를 flutter plugin에 포함시키는 방법을 알아봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 kmp로 작성한 코드를 windows용도의 dll로 빌드하고 flutter plugin으로 만드는 방법을 설명합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하고자 하는것은 아래와 같은습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;kmp로 공용화시킬 함수를 작성한다&lt;/li&gt;
&lt;li&gt;windows 용 dll 파일로 빌드한다.&lt;/li&gt;
&lt;li&gt;flutter plugin에서 dll 파일을 읽어 해당 함수를 호출한다.&lt;/li&gt;
&lt;li&gt;flutter에서 사용 가능하도록 생성한 plugin을 배포한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;호출할 함수의 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flutter에서 dll을 로드하고 함수를 호출하려면 반드시 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;extern C&lt;/span&gt;로 선언된 함수만 가능합니다.&lt;/b&gt; 또한 kmp로 작성한 코드를 flutter에서 호출하려면 &lt;b&gt;이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;top-level function&lt;/span&gt;으로 선언되어야만 가능&lt;/b&gt;합니다. 이 두가지가 가장 핵심이므로 꼭 지켜야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 호출하려는 함수는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;shared/commonMain&lt;/span&gt;&lt;/b&gt;안에 위치해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737875572889&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//TestInterface.kt

@OptIn(ExperimentalNativeApi::class)
@CName(&quot;inputTest&quot;)
fun inputTest(number: String): Int {
    println(&quot;inputTest() - number:$number&quot;)
    return 100
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;shared/commonMain/kotlin/com.xxx.xx.../TestInterface.kt&lt;/span&gt; 를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Top level function으로 &lt;span style=&quot;color: #009a87;&quot;&gt;inputTest() &lt;/span&gt;함수를 생성하고&lt;span style=&quot;color: #006dd7;&quot;&gt; @CName&lt;/span&gt;을 주어 외부에서 호출하기 쉽도록 선언합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Gradle 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shared/build.gradle.kts에 아래와 같이 추가합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737875973652&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kotlin {
   ...
   
   mingwX64(&quot;native&quot;) {
        binaries {
            sharedLib {
                baseName = &quot;TestLib&quot;
            }
        }
    }
    
   ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 하기와 같은 명령어를 수행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737876067293&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;./gradlew&amp;nbsp;linkNative&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 해당 명령어를 gradle task 목록에서 직접 찾아서 수행할수 도 있습니다. (debug, release 각각 따로 빌드 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 해당 빌드는 윈도우 pc에서 수행해야 합니다. (macOS용 xcFramework을 만드는건 mac os에서만 가능하듯이..)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-01-26 오후 4.24.54.png&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;1684&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEHJwJ/btsL02Y7bad/sKvkkbHu9QY1hX8Q2hRBq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEHJwJ/btsL02Y7bad/sKvkkbHu9QY1hX8Q2hRBq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEHJwJ/btsL02Y7bad/sKvkkbHu9QY1hX8Q2hRBq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEHJwJ%2FbtsL02Y7bad%2FsKvkkbHu9QY1hX8Q2hRBq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;267&quot; height=&quot;539&quot; data-filename=&quot;스크린샷 2025-01-26 오후 4.24.54.png&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;1684&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드된 DLL 파일은 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;shared/build/bin/native/&lt;/span&gt;&quot; 폴더 아래 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flutter plugin에서 dll를 load하는 방법은 다음 포스팅에서 확인 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/Kotlin</category>
      <category>cname</category>
      <category>commonmain</category>
      <category>dll 빌드</category>
      <category>Flutter</category>
      <category>kmm</category>
      <category>kmp</category>
      <category>library 빌드</category>
      <category>mingwx64</category>
      <category>shared</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/633</guid>
      <comments>https://tourspace.tistory.com/633#entry633comment</comments>
      <pubDate>Sun, 26 Jan 2025 16:29:28 +0900</pubDate>
    </item>
    <item>
      <title>[Tensorflow] Mac에서 tensorflow 설정</title>
      <link>https://tourspace.tistory.com/632</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;rodion-kutsaiev-PEm_sLmJT-w-unsplash.jpg&quot; data-origin-width=&quot;5955&quot; data-origin-height=&quot;3970&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m4sHA/btsL25Uh5Ui/NbOemmc6D8e1eXjV1jl4d1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m4sHA/btsL25Uh5Ui/NbOemmc6D8e1eXjV1jl4d1/img.jpg&quot; data-alt=&quot;Photy by unsplash&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m4sHA/btsL25Uh5Ui/NbOemmc6D8e1eXjV1jl4d1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm4sHA%2FbtsL25Uh5Ui%2FNbOemmc6D8e1eXjV1jl4d1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5955&quot; height=&quot;3970&quot; data-filename=&quot;rodion-kutsaiev-PEm_sLmJT-w-unsplash.jpg&quot; data-origin-width=&quot;5955&quot; data-origin-height=&quot;3970&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Photy by unsplash&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mac에도 GPU가 있지만 tensorflow 환경 설정치 주로 NVIDIA의 cuda 코드를 사용하는 설정만 나와 있기에 간략하게 사용 방법을 설명해 보겠습니다. (흠..실제로 잘 돌지는....)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Anaconda, VS code 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;anaconda와 visual studio code는 이미 설치되었다고 가정하고 진행 합니다..하지만 아쉬울수 있으니 간략하게 설명하자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 아나콘다를 다운로드 받아 설치 합니다[1] &lt;a href=&quot;https://docs.anaconda.com/anaconda/install/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.anaconda.com/anaconda/install/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2258&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zeDq4/btsL0CzPQ3k/KbiIkLnfHfo311nj3dvCFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zeDq4/btsL0CzPQ3k/KbiIkLnfHfo311nj3dvCFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zeDq4/btsL0CzPQ3k/KbiIkLnfHfo311nj3dvCFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzeDq4%2FbtsL0CzPQ3k%2FKbiIkLnfHfo311nj3dvCFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2258&quot; height=&quot;676&quot; data-origin-width=&quot;2258&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VS Code를 다운로드 받아 설치 합니다.[2] &lt;a href=&quot;https://code.visualstudio.com/download&quot;&gt;https://code.visualstudio.com/download&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFrFwL/btsL2aor8Hf/0QKrC7tduW3zu0N0nR2U80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFrFwL/btsL2aor8Hf/0QKrC7tduW3zu0N0nR2U80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFrFwL/btsL2aor8Hf/0QKrC7tduW3zu0N0nR2U80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFrFwL%2FbtsL2aor8Hf%2F0QKrC7tduW3zu0N0nR2U80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;252&quot; height=&quot;237&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽에 네모 모양의 아이콘을 클릭한뒤 python을 설치 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxnnJ8/btsL2moEAXe/wfQbtUSzcZJgg0kBxD1Duk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxnnJ8/btsL2moEAXe/wfQbtUSzcZJgg0kBxD1Duk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxnnJ8/btsL2moEAXe/wfQbtUSzcZJgg0kBxD1Duk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxnnJ8%2FbtsL2moEAXe%2FwfQbtUSzcZJgg0kBxD1Duk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;262&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 나서 jupyter로 설치해 줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Anaconda 가상환경 생성 및 tensorflow 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;anaconda가 이미 환경변수에 추가되었다는 가정하에 하기 명령어를 입력하여 현재 가상환경을 확인 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737862030868&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda env list&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-01-26 오후 12.27.44.png&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q6Mg4/btsL0YXdlCy/M81KVEjoarDtSEep05rDhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q6Mg4/btsL0YXdlCy/M81KVEjoarDtSEep05rDhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q6Mg4/btsL0YXdlCy/M81KVEjoarDtSEep05rDhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq6Mg4%2FbtsL0YXdlCy%2FM81KVEjoarDtSEep05rDhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;175&quot; data-filename=&quot;스크린샷 2025-01-26 오후 12.27.44.png&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이미 &lt;span style=&quot;color: #ee2323;&quot;&gt;tensorflow&lt;/span&gt;라는 이름으로 환경을 만들었지만 기본적으로는 &lt;span style=&quot;color: #ee2323;&quot;&gt;base&lt;/span&gt;만 존재 합니다. 그리고 기본적으로 * 표시는 현재 선택된 환경을 의미 합니다. 처음 생성하면 base에 * 표시가 되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하기 명령어로 새로운 virtual 환경을 만들고 activate 시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737862401525&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n tensorflow python=3.9 //'tensorflow' 라는 가상환경 생성, 버전은 3.9
conda activate tensorflow //'tensorflow' 환경을 사용하도록 변경&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 한번 conda env list를 실행하면 위 그림처럼 tensorflow에 * 표시가 된것을 알수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 python의 버전은 3.12.xx까지 나와 있으나, 해당 버전으로 설치시 tensorflow가 설치가 안되더군요... 따라서 실행 최소 버전인 3.9를 명시적으로 넣고 virtual 환경을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 'python=3.9' 부분을 생략하면 가장 최신 버전의 python을 설치하여 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737862691643&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda install -c apple tensorflow-deps //Apple 의존성 설치
pip intall tensorflow //tensorflow 설치
pip install tensorflow-metal // GPU 지원&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 새로 생성한 가상 공간에 tensorflow를 설치해 줍니다.[3][4]&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Tensorflow 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VS code에서 ipynb 파일을 하나 생성합니다. &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;Command + Shift + P&lt;/span&gt;&quot;를 누르면 선택창이 뜨고, &quot;jupyter&quot;를 입력하면 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;Create: New Jupyter NoteBook&lt;/span&gt;&quot; 을 선택할수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddaGUX/btsL1yXrBCn/PLsTkRBkxK0v1oDB1WHeB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddaGUX/btsL1yXrBCn/PLsTkRBkxK0v1oDB1WHeB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddaGUX/btsL1yXrBCn/PLsTkRBkxK0v1oDB1WHeB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddaGUX%2FbtsL1yXrBCn%2FPLsTkRBkxK0v1oDB1WHeB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1610&quot; height=&quot;248&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 주피터 노트북 파일 하나 생깁니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEudNz/btsL2SglMfr/b5WbAjphsHWBk2dT60XgvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEudNz/btsL2SglMfr/b5WbAjphsHWBk2dT60XgvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEudNz/btsL2SglMfr/b5WbAjphsHWBk2dT60XgvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEudNz%2FbtsL2SglMfr%2Fb5WbAjphsHWBk2dT60XgvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1398&quot; height=&quot;280&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이 주피터 파일을 수행할 interpreter를 아까 생성해 놓은 가상 머신으로 바꿔 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;Command + Shift + P&lt;/span&gt;&quot;를 눌러 선택창에서 &quot;Interpre&quot;를 입력하면 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;Python: Select Interpreter&lt;/span&gt;&quot; 을 선택할수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7GPS6/btsL00AaU4A/PNu5ujFniOa38ew1MuJ66K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7GPS6/btsL00AaU4A/PNu5ujFniOa38ew1MuJ66K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7GPS6/btsL00AaU4A/PNu5ujFniOa38ew1MuJ66K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7GPS6%2FbtsL00AaU4A%2FPNu5ujFniOa38ew1MuJ66K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1640&quot; height=&quot;246&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이미 생성해 놓은 여러 interpreter들이 나열되는데, 아까 만들어 놓은 'tensorflow'를 선택합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exOBOU/btsL2kRUAz5/S8HJLxHNMz4AHoEWfI3Qe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exOBOU/btsL2kRUAz5/S8HJLxHNMz4AHoEWfI3Qe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exOBOU/btsL2kRUAz5/S8HJLxHNMz4AHoEWfI3Qe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexOBOU%2FbtsL2kRUAz5%2FS8HJLxHNMz4AHoEWfI3Qe0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;197&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우상단에 현재 사용하고 있는 interpreter가 사진과 같이 보여집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3SsX8/btsL2f38x09/bPm9bb3tpRxgvbz28EdW0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3SsX8/btsL2f38x09/bPm9bb3tpRxgvbz28EdW0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3SsX8/btsL2f38x09/bPm9bb3tpRxgvbz28EdW0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3SsX8%2FbtsL2f38x09%2FbPm9bb3tpRxgvbz28EdW0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1448&quot; height=&quot;196&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 간단하게 잘 설치되었는지 아래 코드르 넣어서 실행 시킵니다.[3]&lt;/p&gt;
&lt;pre id=&quot;code_1737863499926&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import tensorflow as tf

# Check for tensorflow GPU acess
print(&quot;TensorFlow has access to the following devices:&quot;, tf.config.list_physical_devices())

# See TensorFlow version
print(&quot;TensorFlow version:&quot;, tf.__version__)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2686&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pgqsQ/btsL2avg5Bc/IS53LhAQI5XXzlKFqXmslk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pgqsQ/btsL2avg5Bc/IS53LhAQI5XXzlKFqXmslk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pgqsQ/btsL2avg5Bc/IS53LhAQI5XXzlKFqXmslk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpgqsQ%2FbtsL2avg5Bc%2FIS53LhAQI5XXzlKFqXmslk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2686&quot; height=&quot;462&quot; data-origin-width=&quot;2686&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치된 tensorflow의 버전과 사용할수 있는 CPU / GPU를 표시해 줍니다. (이 코드 몇줄 수행하는데 40s나 걸렸네요..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 확인을 위해서 metal 설명 페이지에서 제시한 실제 learning을 돌리는 코드를 수행해 볼수도 있습니다. [4]&lt;/p&gt;
&lt;pre id=&quot;code_1737863926828&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import tensorflow as tf

cifar = tf.keras.datasets.cifar100
(x_train, y_train), (x_test, y_test) = cifar.load_data()
model = tf.keras.applications.ResNet50(
    include_top=True,
    weights=None,
    input_shape=(32, 32, 3),
    classes=100,)

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
model.compile(optimizer=&quot;adam&quot;, loss=loss_fn, metrics=[&quot;accuracy&quot;])
model.fit(x_train, y_train, epochs=5, batch_size=64)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 구동 화면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n3mJG/btsL26eCi4m/N9QRKKVNnrEInDXLOMrPfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n3mJG/btsL26eCi4m/N9QRKKVNnrEInDXLOMrPfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n3mJG/btsL26eCi4m/N9QRKKVNnrEInDXLOMrPfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn3mJG%2FbtsL26eCi4m%2FN9QRKKVNnrEInDXLOMrPfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1990&quot; height=&quot;1274&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Virtual env 삭제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지우기 위해서는 먼저 activate가 된 상태이면 불가 합니다. 따라서 base로 activate를 돌린 이후에 삭제를 진행 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1738321051243&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda activate base
conda remove --name tensorflow --all&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Reference&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://docs.anaconda.com/anaconda/install/&quot;&gt;https://docs.anaconda.com/anaconda/install/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://code.visualstudio.com/download&quot;&gt;https://code.visualstudio.com/download&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://toward-the-future.tistory.com/entry/MacOS&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toward-the-future.tistory.com/entry/MacOS&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://developer.apple.com/metal/tensorflow-plugin/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.apple.com/metal/tensorflow-plugin/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/Python</category>
      <category>Anaconda</category>
      <category>jupyter</category>
      <category>keras</category>
      <category>Metal</category>
      <category>Python</category>
      <category>tensorflow mac</category>
      <category>visual studio code</category>
      <category>vscode</category>
      <category>파이썬 설치</category>
      <category>환경설정</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/632</guid>
      <comments>https://tourspace.tistory.com/632#entry632comment</comments>
      <pubDate>Sun, 26 Jan 2025 12:10:23 +0900</pubDate>
    </item>
    <item>
      <title>[KMP] KMP 라이브러리를 Flutter에서 사용하기 - Flutter Plugin에 KMP xcFramework Library import #2</title>
      <link>https://tourspace.tistory.com/631</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k0fUP/btsLMV6Map3/lV4yoVApUklDgH4rVQLk2K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k0fUP/btsLMV6Map3/lV4yoVApUklDgH4rVQLk2K/img.jpg&quot; data-alt=&quot;Photo by unsplash&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k0fUP/btsLMV6Map3/lV4yoVApUklDgH4rVQLk2K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk0fUP%2FbtsLMV6Map3%2FlV4yoVApUklDgH4rVQLk2K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7781&quot; height=&quot;4377&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Photo by unsplash&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전글에서 생성한 xcfFramework을 flutter plugin으로 만드는 과정을 설명합니다. 이렇게 만들면 KMP를 통해서 생성한 library를 flutter에도 plugin 형태로 배포할수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Flutter Plugin Project 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Flutter Plugin Project를 생성합니다. Android studio에서 flutter plugin이 설정되어 있다면 &quot;&lt;span style=&quot;color: #006dd7;&quot;&gt;File -&amp;gt; New -&amp;gt; New Flutter Project&lt;/span&gt;&quot;에서도 UI를 통해서 만들수 있지만, 여기서는 cmd 명령어로 생성해 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736840195170&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;flutter create --template=plugin --platforms=windows,macos kmm_plugin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;plugin 템플릿을 사용하고, windows와 macos에서 사용할수 있도록 합니다. &lt;i&gt;(물론 window에서는 생성된 library를 호출하지 않습니다만, 추후 desktop을 지원하기 위하여 추가해 놓습니다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;project 이름은 &lt;span style=&quot;color: #409d00;&quot;&gt;kmm_plugin&lt;/span&gt;으로 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 project는 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;1314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uKudP/btsLNxK66AF/SZFl5k5S9bhwyQ0xIBja9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uKudP/btsLNxK66AF/SZFl5k5S9bhwyQ0xIBja9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uKudP/btsLNxK66AF/SZFl5k5S9bhwyQ0xIBja9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuKudP%2FbtsLNxK66AF%2FSZFl5k5S9bhwyQ0xIBja9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;423&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;1314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;example&lt;/b&gt;: 생성된 plugin을 테스트해 볼수 있도록 flutter에서 제공하는 폴더 (main.dart가 존재)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;lib&lt;/b&gt;: import된 library를 wrapping하여 dart함수를 제공하는 부분&lt;/li&gt;
&lt;li&gt;&lt;b&gt;macos&lt;/b&gt;: import된 library를 위치시키고 plugin에 연결하기위해 설정하는 부분&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;macos 폴더 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 이전에 빌드한 framework을 그대로 macos아래로 복사합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0lE6g/btsLM0mEVZD/RO4GckY0tpsu8Zz229AHKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0lE6g/btsLM0mEVZD/RO4GckY0tpsu8Zz229AHKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0lE6g/btsLM0mEVZD/RO4GckY0tpsu8Zz229AHKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0lE6g%2FbtsLM0mEVZD%2FRO4GckY0tpsu8Zz229AHKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;453&quot; height=&quot;273&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 framework중에 debug 용으로 생성된 framework을 이동시키겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6rTN8/btsLMohfy6L/6ZshV6nfcj06tQvQ2YQDh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6rTN8/btsLMohfy6L/6ZshV6nfcj06tQvQ2YQDh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6rTN8/btsLMohfy6L/6ZshV6nfcj06tQvQ2YQDh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6rTN8%2FbtsLMohfy6L%2F6ZshV6nfcj06tQvQ2YQDh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;392&quot; height=&quot;385&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 project 구조로 봤을때 최상위의 &lt;span style=&quot;color: #006dd7;&quot;&gt;macos/share.xcframework&lt;/span&gt;에 위치하게 됩니다. (example 안에도 macos 폴더가 있습니다만 거기에 복사하는게 아닙니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 캡쳐사진에 보이는 &lt;span style=&quot;color: #006dd7;&quot;&gt;macos/kmm_plugin.podspec&lt;/span&gt;에 아래와 vendored_frameworks를 같이 추가합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736845852966&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  s.vendored_frameworks = 'shared.xcframework'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 '&lt;span style=&quot;color: #409d00;&quot;&gt;shared.xcframework&lt;/span&gt;'은 방금 복사해서 넣은 이름을 넣어야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 추가되고 나면 &lt;span style=&quot;color: #409d00;&quot;&gt;kmm_plugin.podspec&lt;/span&gt; 파일은 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736845843203&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Pod::Spec.new do |s|
  s.name             = 'kmm_plugin'
  s.version          = '0.0.1'
  ...
  s.swift_version = '5.0'
  s.vendored_frameworks = 'shared.xcframework'
end&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널을 열어 &quot;&lt;b&gt;example/macos/&lt;/b&gt;&quot;로 이동한 후 하기 명령어를 수행하여 Runner.xcworkspace 파일에 추가한 xcframework을 통합 시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737880436126&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pod install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Library 호출을 위한 macos 작업&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exK2ye/btsLNU6683R/rIbX20ear0iWh9kpOr3IjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exK2ye/btsLNU6683R/rIbX20ear0iWh9kpOr3IjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exK2ye/btsLNU6683R/rIbX20ear0iWh9kpOr3IjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexK2ye%2FbtsLNU6683R%2FrIbX20ear0iWh9kpOr3IjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;261&quot; height=&quot;307&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하기 위치의 &lt;span style=&quot;color: #ee2323;&quot;&gt;macos/KmmPlugin.swift&lt;/span&gt; 를 열면 아래와 같이 기본설정이 되어 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736848563423&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class KmmPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: &quot;kmm_plugin&quot;, binaryMessenger: registrar.messenger)
    let instance = KmmPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case &quot;getPlatformVersion&quot;:
      result(&quot;macOS &quot; + ProcessInfo.processInfo.operatingSystemVersionString)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이미 &lt;span style=&quot;color: #ee2323;&quot;&gt;methodChannel&lt;/span&gt;이 연결되어 있고, 추가한 함수만 새로 정의하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;참고로 KMP에서 kotlin 코드로 생성했던 함수는 아래와 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yhyhQ/btsLNYVSWHH/5WDKNj7aqcS1kkO9YiQ1ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yhyhQ/btsLNYVSWHH/5WDKNj7aqcS1kkO9YiQ1ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yhyhQ/btsLNYVSWHH/5WDKNj7aqcS1kkO9YiQ1ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyhyhQ%2FbtsLNYVSWHH%2F5WDKNj7aqcS1kkO9YiQ1ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;345&quot; height=&quot;172&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수를 호출할수 있도록 library의 &lt;b&gt;baseName&lt;/b&gt;을 import해주고, &lt;span style=&quot;color: #409d00;&quot;&gt;handle()&lt;/span&gt;쪽에 아래와 같이 추가해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736848946183&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Cocoa
import FlutterMacOS
import Shared //import 추가 kmm 빌드시 사용했던 baseName

public class KmmPlugin: NSObject, FlutterPlugin {
 ...
  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case &quot;getPlatformVersion&quot;:
      result(&quot;macOS &quot; + ProcessInfo.processInfo.operatingSystemVersionString)
    // library에 정의한 함수 추가
    case &quot;connectTest&quot;:
      let resultValue = MyLibInterface().connectTest()
            result(resultValue)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 baseName은 kmm project에서 아래와 같이 build.gradle.kt에&amp;nbsp;설정한 이름 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zrREh/btsLN0TLwqe/zsBPvkH1J6lGK5SrENY4R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zrREh/btsLN0TLwqe/zsBPvkH1J6lGK5SrENY4R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zrREh/btsLN0TLwqe/zsBPvkH1J6lGK5SrENY4R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzrREh%2FbtsLN0TLwqe%2FzsBPvkH1J6lGK5SrENY4R0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;284&quot; height=&quot;238&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 빌드쪽 포스팅에서 언급했지만 &lt;span style=&quot;color: #009a87;&quot;&gt;connectTest()&lt;/span&gt;함수는 class의 멤버함수로 객체의 instance가 필요합니다. 따라서 여기서는 &lt;span style=&quot;color: #009a87;&quot;&gt;MyLibInterface()&lt;/span&gt;라는 객체 생성후에 호출하도록 하였으나, &lt;b&gt;사실 이는 바람직 하지 않습니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 호출이 되기는 하나, 함수가 parameter를 받는 형태라면 호출 실패가 날수도 있습니다. 따라서 kmp에서 함수는 top-level function으로 노출되어야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737881306719&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//MyLibInterface.kt

@OptIn(ExperimentalNativeApi::class)
@CName(&quot;test&quot;)
fun test(): String {
    return &quot;Connection Test Success !!!&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위와 같은 함수를 MyLibInterface.kt 파일에서 Top-level 함수로 노출시켜 놓았다면 아래와 같이 호출함수를 만들어야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737881478838&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Cocoa
import FlutterMacOS
import Shared //import 추가 kmm 빌드시 사용했던 baseName

public class KmmPlugin: NSObject, FlutterPlugin {
 ...
  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
      ...
    case &quot;connectTest&quot;:
      ...
    case &quot;test&quot;:
      let topLevelFuncResult = MyLibInterfaceKt .test()
            result(topLevelFuncResult)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출시 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;파일명Kt.함수명()&lt;/span&gt;&quot;으로 호출해야 정상적으로 호출됩니다. -&amp;gt; &lt;span style=&quot;color: #009a87;&quot;&gt;MyLibInterface&lt;b&gt;Kt&lt;/b&gt;.test()&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Library 호출을 위한 Dart wrapping&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 lib 폴더의 파일을 수정하여 library에서 생성한 함수를 호출할수 있도록 native 함수를 dart로 wrapping하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LutFM/btsLNtPzn1Y/lfHSIiK4LUhhS3P7JYtvP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LutFM/btsLNtPzn1Y/lfHSIiK4LUhhS3P7JYtvP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LutFM/btsLNtPzn1Y/lfHSIiK4LUhhS3P7JYtvP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLutFM%2FbtsLNtPzn1Y%2FlfHSIiK4LUhhS3P7JYtvP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;358&quot; height=&quot;196&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;kmm_plugin_method_interface.dart &lt;span style=&quot;color: #000000;&quot;&gt;파일을 엽니다. 기본적인 코드는 하기와 같이 작성되어 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736846439919&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;abstract class KmmPluginPlatform extends PlatformInterface {
  /// Constructs a KmmPluginPlatform.
  KmmPluginPlatform() : super(token: _token);

  static final Object _token = Object();

  static KmmPluginPlatform _instance = MethodChannelKmmPlugin();

...

  Future&amp;lt;String?&amp;gt; getPlatformVersion() {
    throw UnimplementedError('platformVersion() has not been implemented.');
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실제 추가해 놓은 함수를 여기에 정의 합니다. 이 interface는 &lt;span style=&quot;color: #ee2323;&quot;&gt;kmm_plugin_method_channel.dart&lt;/span&gt;에서 상속받아 구현합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;lib에서 생성했던 함수의 정의를 아래와 같이 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736846947986&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;abstract class KmmPluginPlatform extends PlatformInterface {
...

  static set instance(KmmPluginPlatform instance) {
    PlatformInterface.verifyToken(instance, _token);
    _instance = instance;
  }

  Future&amp;lt;String?&amp;gt; getPlatformVersion() {
    throw UnimplementedError('platformVersion() has not been implemented.');
  }

  //호출할 함수 추가
  Future&amp;lt;String&amp;gt; connectTest() {
    throw UnimplementedError('connectTest() has not been implemented.');
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이제 kmm_plugin_method_channel.dart&lt;/span&gt; 파일을 열어 위에서 정의해 놓은 함수를 override 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736846234485&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/// An implementation of [KmmPluginPlatform] that uses method channels.
class MethodChannelKmmPlugin extends KmmPluginPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('kmm_plugin');

  @override
  Future&amp;lt;String?&amp;gt; getPlatformVersion() async {
    final version = await methodChannel.invokeMethod&amp;lt;String&amp;gt;('getPlatformVersion');
    return version;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 channel을 생성해 놓고 있습니다. 이때 &lt;span style=&quot;color: #006dd7;&quot;&gt;MethodChannel&lt;/span&gt;의 '&lt;span style=&quot;color: #409d00;&quot;&gt;kmm_plugin&lt;/span&gt;'은 프로젝트 이름으로 다른 plugin과 중복되지 않도록 하기위해 자동으로 프로젝트 이름으로 설정 됩니다. invokeMethod()를 통해서 호출하며, 이때 인자로 함수명을 적어줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736847150444&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/// An implementation of [KmmPluginPlatform] that uses method channels.
class MethodChannelKmmPlugin extends KmmPluginPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('kmm_plugin');

  @override
  Future&amp;lt;String?&amp;gt; getPlatformVersion() async {
    final version = await methodChannel.invokeMethod&amp;lt;String&amp;gt;('getPlatformVersion');
    return version;
  }
  
  //library 함수를 호출
  @override
  Future&amp;lt;String&amp;gt; connectTest() async {
    final connectMsg = await methodChannel.invokeMethod&amp;lt;String&amp;gt;('connectTest');
    if (connectMsg == null) {
      return 'library connection failed';
    } else {
      return connectMsg;  
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 kmm_plugin.dart를 열고, 새로 추가한 connectTest()함수를 추가합니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;class KmmPlugin {
  Future&amp;lt;String?&amp;gt; getPlatformVersion() {
    return KmmPluginPlatform.instance.getPlatformVersion();
  }

  //실제 외부에서 호출되는 함수
  Future&amp;lt;String&amp;gt; connectTest() {
    return KmmPluginPlatform.instance.connectTest();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로써 plugin에 library 연결은 끝났습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 test를 통해 해당 함수가 잘 호출되는지 확인하면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;example을 통한 동작 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 example package를 이용하여 plugin에 추가한 함수를 호출해 보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;1218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDQobW/btsLNXbHxoM/6lK4lkzoKjFTPBmDBmGcM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDQobW/btsLNXbHxoM/6lK4lkzoKjFTPBmDBmGcM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDQobW/btsLNXbHxoM/6lK4lkzoKjFTPBmDBmGcM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDQobW%2FbtsLNXbHxoM%2F6lK4lkzoKjFTPBmDBmGcM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;302&quot; height=&quot;461&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;1218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;example/lib/main.dart&lt;/span&gt; 함수를 열면 이미 기본적인 샘플 코드가 들어가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 실행하면 아래와 같은 화면이 뜨면 maing.dart의 코드는 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFEVQh/btsLM4iizW7/1rQpd91COtWf2oG24w1wlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFEVQh/btsLM4iizW7/1rQpd91COtWf2oG24w1wlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFEVQh/btsLM4iizW7/1rQpd91COtWf2oG24w1wlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFEVQh%2FbtsLM4iizW7%2F1rQpd91COtWf2oG24w1wlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;328&quot; height=&quot;257&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1736847563014&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State&amp;lt;MyApp&amp;gt; createState() =&amp;gt; _MyAppState();
}

class _MyAppState extends State&amp;lt;MyApp&amp;gt; {
  String _platformVersion = 'Unknown';
  final _kmmPlugin = KmmPlugin();

  @override
  void initState() {
   ...
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future&amp;lt;void&amp;gt; initPlatformState() async {
     ...
  }

  @override
  Widget build(BuildContext context) {
    ...
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 화면에 libraray를 호출하여 받은 string을 하위에 노출시켜 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 주석으로 처리된 코드를 넣어 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736849245025&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State&amp;lt;MyApp&amp;gt; createState() =&amp;gt; _MyAppState();
}

class _MyAppState extends State&amp;lt;MyApp&amp;gt; {
  String _platformVersion = 'Unknown';
  final _kmmPlugin = KmmPlugin();

  String _kmmLibConnectValue = &quot;Not connected!&quot;; //추가

  @override
  void initState() {
    super.initState();
    initPlatformState();
    connectMacOSLibrary(); //추가
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future&amp;lt;void&amp;gt; initPlatformState() async {
     ...
  }

  // 추가
  Future&amp;lt;void&amp;gt; connectMacOSLibrary() async {
    String connectValue;
    try {
      connectValue =
          await _kmmPlugin.connectTest();
    } on PlatformException {
      connectValue = 'Failed to connect mac os';
    }

    if (!mounted) return;

    setState(() {
      _kmmLibConnectValue = connectValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          //추가 - 마지막에 호출한 함수의 결과값이 담인 _KmmLibConnectValue를 찍도록 함.
          child: Text('Running on: $_platformVersion\n\n lib connect: $_kmmLibConnectValue'),
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 실행하면 아래와 같은 화면이 나타납니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-01-14 오후 7.08.18.png&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ph33d/btsLNbnZ2Ua/wEORDNk7sSg6lRZKlSFkM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ph33d/btsLNbnZ2Ua/wEORDNk7sSg6lRZKlSFkM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ph33d/btsLNbnZ2Ua/wEORDNk7sSg6lRZKlSFkM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPh33d%2FbtsLNbnZ2Ua%2FwEORDNk7sSg6lRZKlSFkM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;518&quot; height=&quot;408&quot; data-filename=&quot;스크린샷 2025-01-14 오후 7.08.18.png&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 library에서 호출하는 함수가 network에 접근해야 한다면 아래와 같은 permission을 추가 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; Network 권한 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;network 권한은 plugin을 호출하는 외부 앱에 선언되어 있어야 합니다. (&lt;/b&gt;즉 plugin 프로젝트에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;example/macos/Runner&lt;/span&gt; 내부의 파일에 권한을 추가해야 합니다.)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;example/macos/Runner/DebugProfile.entitlements&lt;/li&gt;
&lt;li&gt;example/macos/Runner/Release.entitlements&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 내부에 아래 내용을 추가 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737882353626&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;key&amp;gt;com.apple.security.network.client&amp;lt;/key&amp;gt;
    &amp;lt;true/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 파일에서 추가 위치&lt;/p&gt;
&lt;pre id=&quot;code_1737882326418&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
    ...
    &amp;lt;key&amp;gt;com.apple.security.network.client&amp;lt;/key&amp;gt;
    &amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;https 가 아닌 http url에 접속시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;info.plist에 아래 권한 추가&lt;/p&gt;
&lt;pre id=&quot;code_1737882385598&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;key&amp;gt;NSAppTransportSecurity&amp;lt;/key&amp;gt;
    &amp;lt;dict&amp;gt;
        &amp;lt;key&amp;gt;NSAllowsArbitraryLoads&amp;lt;/key&amp;gt;
        &amp;lt;true/&amp;gt;
    &amp;lt;/dict&amp;gt;
    &amp;lt;key&amp;gt;NSLocalNetworkUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;로컬 네트워크에 접근하기 위해 필요합니다.&amp;lt;/string&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 파일에서 추가 위치&lt;/p&gt;
&lt;pre id=&quot;code_1737882143243&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
    &amp;lt;key&amp;gt;NSAppTransportSecurity&amp;lt;/key&amp;gt;
    &amp;lt;dict&amp;gt;
        &amp;lt;key&amp;gt;NSAllowsArbitraryLoads&amp;lt;/key&amp;gt;
        &amp;lt;true/&amp;gt;
    &amp;lt;/dict&amp;gt;
    &amp;lt;key&amp;gt;NSLocalNetworkUsageDescription&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;로컬 네트워크에 접근하기 위해 필요합니다.&amp;lt;/string&amp;gt;	
    ...
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;References&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://proandroiddev.com/how-to-use-kmp-library-inside-the-flutter-plugin-5f74722c7b3c&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://proandroiddev.com/how-to-use-kmp-library-inside-the-flutter-plugin-5f74722c7b3c&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발이야기/Kotlin</category>
      <category>Flutter</category>
      <category>flutter desktop</category>
      <category>flutter plugin</category>
      <category>kmm</category>
      <category>kmm flutter import</category>
      <category>kmm library</category>
      <category>kmm 빌드</category>
      <category>kmp</category>
      <category>macos desktop</category>
      <category>XCFramework</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/631</guid>
      <comments>https://tourspace.tistory.com/631#entry631comment</comments>
      <pubDate>Tue, 14 Jan 2025 16:41:30 +0900</pubDate>
    </item>
    <item>
      <title>[KMP] KMP 라이브러리를 Flutter에서 사용하기 - MacOS SharedLibrary 빌드 #1</title>
      <link>https://tourspace.tistory.com/630</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lij4I/btsLNNfQPTC/lQlpuQ2ql088gzCs8o9Qe1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lij4I/btsLNNfQPTC/lQlpuQ2ql088gzCs8o9Qe1/img.jpg&quot; data-alt=&quot;Photo by unsplash&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lij4I/btsLNNfQPTC/lQlpuQ2ql088gzCs8o9Qe1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flij4I%2FbtsLNNfQPTC%2FlQlpuQ2ql088gzCs8o9Qe1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7781&quot; height=&quot;4377&quot; data-filename=&quot;wolfgang-weiser-GPRyx0EM5uE-unsplash.jpg&quot; data-origin-width=&quot;7781&quot; data-origin-height=&quot;4377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Photo by unsplash&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mutilple OS에 공용 library를 delivery하기 위해서 Kotlin MultiPlatform을 사용합니다. 일반적인 목적, 구조에 대한 설명들은&amp;nbsp; 이미 많은 블로그나 정리된 문서들에서 다루고 있으니, 여기서는 shared에 위치한 MacOS 코드를 bulid하는&amp;nbsp; 절차를 간단하게 정리해 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 목적은 Flutter의 Mac OS Desktop에 KMP에서 빌드된 라이브러리를 적용하기 위한 첫번째 작업입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 Multi platform인 Flutter에서 KMP Library를 import 해서 사용한다는 생각이 무리라고 여겨 질 수는 있으나, 상황에 따라 KMP로 만든 공용 library를 AOS, iOS native에 제공하고 flutter에 까지 제공 가능하다면 활용성 범위에서 매력적일 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;호출할 함수의 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KMP 프로젝트를 생성하면&amp;nbsp; 하기와 같은 구조로 생성됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/omE0W/btsLNvGpS4Q/XYHwImDkiQTTsDoOIwITu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/omE0W/btsLNvGpS4Q/XYHwImDkiQTTsDoOIwITu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/omE0W/btsLNvGpS4Q/XYHwImDkiQTTsDoOIwITu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FomE0W%2FbtsLNvGpS4Q%2FXYHwImDkiQTTsDoOIwITu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;250&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;androidMain&lt;/b&gt;: android에서 전용으로 사용 할 소스코드를 포함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;commonMain&lt;/b&gt;: 각 Platform에서 공용으로 들어갈 소스 코드를 포함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;iosMain&lt;/b&gt;: ios에서 전용으로 사용 할 소스코드를 포함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;jvmMain&lt;/b&gt;: jvm으로 빌드&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS와 MacOS를 기본적을 동일한 구조를 갖는다고는 하지만 macOS에서만 따로 호출할 수 있는 코드를 하나 정의 하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o4vhA/btsLN4BruZm/5m7Ve7kFHAM0wXjXNW91p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o4vhA/btsLN4BruZm/5m7Ve7kFHAM0wXjXNW91p1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o4vhA/btsLN4BruZm/5m7Ve7kFHAM0wXjXNW91p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo4vhA%2FbtsLN4BruZm%2F5m7Ve7kFHAM0wXjXNW91p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;325&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 src에 macosMain 폴더를 위와 같은 구조로 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jvmMain이나 iosMain도 동일한 구조를 가지고 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736837900030&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'macosMain/kotlin/com.example.test.sample'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform.macos.kt는 공통으로 적용해야 하는 함수가 있기 때문에 jvmMain이나, iosMain등에서 복사해와서 적절하게 변경해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736838052249&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Platform.macos.kt

class MACOSPlatform: Platform {
    override val name: String = &quot;Mac OS!&quot;
}
actual fun getPlatform(): Platform = MACOSPlatform()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;getPlatform()&lt;/span&gt; 함수는 commonMain에서 expect로 설정된 함수이기 때문에 반드시 구현해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 테스트를 위해 외부에서 호출할 함수 하나를 정의해 줍니다. 위 캡쳐된 구조에서 MyLibInterface를 아래와 같이 구성하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736838645446&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//MyLibInterface.kt

class MyLibInterface {
    fun connectTest(): String {
        println(&quot;Mac OS Connected&quot;)
        return &quot;Mac OS Connected&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출시 단순히 Mac OS Connected를 찍습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qjXrr/btsLM7ZZikD/mHiKWzSutKttHqj7ahfUkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qjXrr/btsLM7ZZikD/mHiKWzSutKttHqj7ahfUkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qjXrr/btsLM7ZZikD/mHiKWzSutKttHqj7ahfUkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqjXrr%2FbtsLM7ZZikD%2FmHiKWzSutKttHqj7ahfUkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;232&quot; height=&quot;132&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 KMP에서 만든 함수를 라이브러리로 만들어 외부에서 호출되도록 하는경우 빌드가&lt;span style=&quot;color: #ee2323;&quot;&gt; extern C&lt;/span&gt;로 되어야 하며, &lt;span style=&quot;color: #ee2323;&quot;&gt;Top-level function&lt;/span&gt;을 권고하고 있습니다. &lt;b&gt;MacOS와 Windows 모두에게서 호출되는 함수를 선언하려면 아래와 같이 함수를 선언해야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/znXYo/btsL2QbMvES/gnisKaj0Gz3PSB2xGcx0T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/znXYo/btsL2QbMvES/gnisKaj0Gz3PSB2xGcx0T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/znXYo/btsL2QbMvES/gnisKaj0Gz3PSB2xGcx0T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FznXYo%2FbtsL2QbMvES%2FgnisKaj0Gz3PSB2xGcx0T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;156&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;@CName&lt;/span&gt;은 외부에서 함수 호출시 package명부터 시작하여 함수 이름까지 전체의 경로로 호출하지 않고 정해진 이름으로 호출할 수 있도록 도와 줍니다. &lt;b&gt;(단! 동일한 이름이 존재해서는 안됩니다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;instance를 생성하고 나서 호출해야 하는 방법과 Top-level function으로 선언했을때의 함수를 호출하는 방법은 다음 글에서 상세하게 다룹니다. 다만, &lt;span style=&quot;color: #006dd7;&quot;&gt;Top-level function&lt;/span&gt;과 &lt;span style=&quot;color: #006dd7;&quot;&gt;@CName&lt;/span&gt;을 사용하는 방법을 권고하며, 위 &lt;span style=&quot;color: #409d00;&quot;&gt;connectTest()&lt;/span&gt;처럼 instance를 생성하여 호출하는 방법은 지양해야 합니다. &lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;XCFramework 빌드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 shared계위의 build.gradle.kts에 빌드를 설정 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736838773990&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kotlin {
    androidTarget {
       ...
    }

////////// 이 부분을 변경 - START //////////////
    val xcFramework = XCFramework()

    listOf(
//        iosX64(),
//        iosArm64(),
//        iosSimulatorArm64(),
        macosX64(),
        macosArm64()
    ).forEach { iosTarget -&amp;gt;
        iosTarget.binaries.framework {
            baseName = &quot;Shared&quot;
            xcFramework.add(this)
        }
    }
////////// 이 부분을 변경 - END //////////////

    jvm()
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에서 import하기위해서 &lt;span style=&quot;color: #ee2323;&quot;&gt;XCFramework()&lt;/span&gt;으로 한번에 만들어 빌드하도록 합니다. 그렇지 않으면 각 os별로 따로 빌드되어 Xcode에서 다시 xcxFramework으로 합치는 작업을 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XCfFramework()을 생성하여 macosX64()와&amp;nbsp; &lt;span style=&quot;color: #ee2323;&quot;&gt;macosArm64()&lt;/span&gt;를 scfFramework으로 묶습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;span style=&quot;color: #ee2323;&quot;&gt;baseName&lt;/span&gt;은(&quot;&lt;span style=&quot;color: #009a87;&quot;&gt;Shared&lt;/span&gt;&quot;) 외부에서 import할 대상이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iosXXX() 빌드는 일단 주석처리해 놓았습니다. 주석처리가 되지 않으면 모두 빌드되어 xcFramework으로 묶이는데, 시간이 오래 걸립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XCFramework()을 추가한후 gradle을 sync하면 오른쪽 gradle창에 &quot;assembleSCFramework&quot;이 생긴걸 볼수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdZt2c/btsLNNUqXJS/9pAsVknmkNw7nFsfk5SE5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdZt2c/btsLNNUqXJS/9pAsVknmkNw7nFsfk5SE5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdZt2c/btsLNNUqXJS/9pAsVknmkNw7nFsfk5SE5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdZt2c%2FbtsLNNUqXJS%2F9pAsVknmkNw7nFsfk5SE5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;319&quot; height=&quot;314&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 명령어를 더블클릭해도 되고, terminal에서 하기 명령어를 수행해도 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1736839308096&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./gradlew assembleXCFramework&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드가 잘 되었다면 하기 경로에서 빌드된 framework을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;934&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nHvDI/btsLNMBbHyy/X5ti9Wn4uU4VVAVF4T0bek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nHvDI/btsLNMBbHyy/X5ti9Wn4uU4VVAVF4T0bek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nHvDI/btsLNMBbHyy/X5ti9Wn4uU4VVAVF4T0bek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnHvDI%2FbtsLNMBbHyy%2FX5ti9Wn4uU4VVAVF4T0bek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;293&quot; height=&quot;411&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;934&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 폴더아래에는 debug와 release가 존재하고 각각 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;shared.xcframework&lt;/span&gt;&quot;을 가지고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Cocoapods를 이용한 빌드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KMP 설치 당시 &lt;span style=&quot;color: #ee2323;&quot;&gt;cocoapods&lt;/span&gt;[1]를 설정했다면 이를 통해서도 빌드를 할수 있습니다. Android studio Gradle 설정창을 보면 아래와 같이 빌드를 할수 있는 명령어 셋이 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tHy1x/btsL1cVgLvL/Ws9WIq5OMEYLJxHzFdF79K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tHy1x/btsL1cVgLvL/Ws9WIq5OMEYLJxHzFdF79K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tHy1x/btsL1cVgLvL/Ws9WIq5OMEYLJxHzFdF79K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtHy1x%2FbtsL1cVgLvL%2FWs9WIq5OMEYLJxHzFdF79K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;314&quot; height=&quot;363&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;debug나 release만 또는 두개모두를 빌드할수 있는 명령어셋이 존재하여 클릭시 '&lt;span style=&quot;color: #ee2323;&quot;&gt;shared/build/cocoapods&lt;/span&gt;' 폴더에서 빌드된 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clUDv9/btsL1gDjqsB/e9EpGSigAeG3DJffHcNzok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clUDv9/btsL1gDjqsB/e9EpGSigAeG3DJffHcNzok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clUDv9/btsL1gDjqsB/e9EpGSigAeG3DJffHcNzok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclUDv9%2FbtsL1gDjqsB%2Fe9EpGSigAeG3DJffHcNzok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;332&quot; height=&quot;261&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;&lt;span style=&quot;color: #0593d3;&quot;&gt;shared.xcframework&lt;/span&gt;&quot;을 가지고 flutter에 import하는 작업은 다음글에 이어 집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;References&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://kotlinlang.org/docs/native-cocoapods.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kotlinlang.org/docs/native-cocoapods.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발이야기/Kotlin</category>
      <category>.framework</category>
      <category>cname</category>
      <category>cocoapods</category>
      <category>kmm</category>
      <category>kmm 라이브러리 빌드</category>
      <category>kmp</category>
      <category>kotlin</category>
      <category>kotlin multi platform</category>
      <category>XCFramework</category>
      <category>플러터</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/630</guid>
      <comments>https://tourspace.tistory.com/630#entry630comment</comments>
      <pubDate>Tue, 14 Jan 2025 16:02:17 +0900</pubDate>
    </item>
    <item>
      <title>[KMM] Windows dll 빌드 방법 및 함수 설정 방법</title>
      <link>https://tourspace.tistory.com/629</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Kotlin&amp;nbsp;Multiplatform을&amp;nbsp;사용하여&amp;nbsp;Windows에서&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;DLL을&amp;nbsp;생성하고&amp;nbsp;사용하는&amp;nbsp;방법은&amp;nbsp;다음과&amp;nbsp;같습니다:&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;DLL&amp;nbsp;생성&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;Kotlin&amp;nbsp;Multiplatform&amp;nbsp;프로젝트&amp;nbsp;설정:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`build.gradle.kts`&amp;nbsp;파일에서&amp;nbsp;Windows&amp;nbsp;타겟을&amp;nbsp;지정하고&amp;nbsp;공유&amp;nbsp;라이브러리를&amp;nbsp;생성하도록&amp;nbsp;설정합니다:&lt;br /&gt;&lt;br /&gt;```kotlin&lt;br /&gt;kotlin&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mingwX64(&quot;native&quot;)&amp;nbsp;{&amp;nbsp;//&amp;nbsp;Windows&amp;nbsp;타겟&amp;nbsp;지정&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;binaries&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sharedLib&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;baseName&amp;nbsp;=&amp;nbsp;&quot;mylib&quot;&amp;nbsp;//&amp;nbsp;DLL&amp;nbsp;파일명&amp;nbsp;지정&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;Kotlin&amp;nbsp;코드&amp;nbsp;작성:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`nativeMain`&amp;nbsp;소스&amp;nbsp;세트에&amp;nbsp;DLL로&amp;nbsp;노출할&amp;nbsp;함수를&amp;nbsp;작성합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`@CName`&amp;nbsp;어노테이션을&amp;nbsp;사용하여&amp;nbsp;C에서&amp;nbsp;호출&amp;nbsp;가능한&amp;nbsp;함수명을&amp;nbsp;지정합니다:&lt;br /&gt;&lt;br /&gt;```kotlin&lt;br /&gt;@CName(&quot;myFunction&quot;)&lt;br /&gt;fun&amp;nbsp;myFunction():&amp;nbsp;Int&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;42&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;DLL&amp;nbsp;빌드:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;터미널에서&amp;nbsp;다음&amp;nbsp;명령을&amp;nbsp;실행하여&amp;nbsp;DLL을&amp;nbsp;생성합니다:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;./gradlew&amp;nbsp;linkNative&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;생성된&amp;nbsp;DLL은&amp;nbsp;`build/bin/native/releaseShared/`&amp;nbsp;디렉토리에&amp;nbsp;위치합니다.&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;Windows에서&amp;nbsp;DLL&amp;nbsp;사용&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;헤더&amp;nbsp;파일&amp;nbsp;생성:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Kotlin&amp;nbsp;컴파일러가&amp;nbsp;자동으로&amp;nbsp;생성한&amp;nbsp;C&amp;nbsp;헤더&amp;nbsp;파일(`mylib_api.h`)을&amp;nbsp;사용합니다.&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;C/C++&amp;nbsp;프로그램에서&amp;nbsp;DLL&amp;nbsp;로드&amp;nbsp;및&amp;nbsp;사용:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;헤더&amp;nbsp;파일을&amp;nbsp;포함하고&amp;nbsp;DLL을&amp;nbsp;로드하여&amp;nbsp;함수를&amp;nbsp;호출합니다:&lt;br /&gt;&lt;br /&gt;```c&lt;br /&gt;#include&amp;nbsp;&amp;lt;windows.h&amp;gt;&lt;br /&gt;#include&amp;nbsp;&quot;mylib_api.h&quot;&lt;br /&gt;&lt;br /&gt;int&amp;nbsp;main()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HMODULE&amp;nbsp;hDLL&amp;nbsp;=&amp;nbsp;LoadLibrary(&quot;mylib.dll&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(hDLL&amp;nbsp;!=&amp;nbsp;NULL)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;typedef&amp;nbsp;int&amp;nbsp;(*MyFunction)();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyFunction&amp;nbsp;myFunction&amp;nbsp;=&amp;nbsp;(MyFunction)GetProcAddress(hDLL,&amp;nbsp;&quot;myFunction&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(myFunction&amp;nbsp;!=&amp;nbsp;NULL)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;result&amp;nbsp;=&amp;nbsp;myFunction();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;Result:&amp;nbsp;%d\n&quot;,&amp;nbsp;result);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FreeLibrary(hDLL);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;0;&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;컴파일&amp;nbsp;및&amp;nbsp;실행:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;C/C++&amp;nbsp;프로그램을&amp;nbsp;컴파일하고&amp;nbsp;실행합니다.&amp;nbsp;DLL&amp;nbsp;파일이&amp;nbsp;실행&amp;nbsp;파일과&amp;nbsp;같은&amp;nbsp;디렉토리에&amp;nbsp;있어야&amp;nbsp;합니다.&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;방법을&amp;nbsp;통해&amp;nbsp;Kotlin&amp;nbsp;Multiplatform에서&amp;nbsp;생성한&amp;nbsp;함수를&amp;nbsp;Windows&amp;nbsp;DLL로&amp;nbsp;만들고&amp;nbsp;C/C++&amp;nbsp;프로그램에서&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다[1][2][14].&lt;br /&gt;&lt;br /&gt;Citations:&lt;br /&gt;[1]&amp;nbsp;&lt;a href=&quot;https://juyeop.tistory.com/72&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://juyeop.tistory.com/72&lt;/a&gt;&lt;br /&gt;[2]&amp;nbsp;&lt;a href=&quot;https://discuss.kotlinlang.org/t/calling-a-dll-in-my-kotlin-multiplatform-project/13616&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://discuss.kotlinlang.org/t/calling-a-dll-in-my-kotlin-multiplatform-project/13616&lt;/a&gt;&lt;br /&gt;[3]&amp;nbsp;&lt;a href=&quot;https://ca.indeed.com/career-advice/career-development/how-to-open-dll-files&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ca.indeed.com/career-advice/career-development/how-to-open-dll-files&lt;/a&gt;&lt;br /&gt;[4]&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic-link_library&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://en.wikipedia.org/wiki/Dynamic-link_library&lt;/a&gt;&lt;br /&gt;[5]&amp;nbsp;&lt;a href=&quot;https://velog.io/@ams770/Android%EC%99%80-iOS%EC%97%90%EC%84%9C-Jetbrains-Compose%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-UI-%EC%BD%94%EB%93%9C-%EA%B3%B5%EC%9C%A0%ED%95%98%EA%B8%B0-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@ams770/Android%EC%99%80-iOS%EC%97%90%EC%84%9C-Jetbrains-Compose%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-UI-%EC%BD%94%EB%93%9C-%EA%B3%B5%EC%9C%A0%ED%95%98%EA%B8%B0-2&lt;/a&gt;&lt;br /&gt;[6]&amp;nbsp;&lt;a href=&quot;https://kotlinlang.org/docs/native-dynamic-libraries.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kotlinlang.org/docs/native-dynamic-libraries.html&lt;/a&gt;&lt;br /&gt;[7]&amp;nbsp;&lt;a href=&quot;https://learn.microsoft.com/en-us/troubleshoot/windows-client/setup-upgrade-and-drivers/dynamic-link-library&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/en-us/troubleshoot/windows-client/setup-upgrade-and-drivers/dynamic-link-library&lt;/a&gt;&lt;br /&gt;[8]&amp;nbsp;&lt;a href=&quot;https://velog.io/@mraz3068/Compose-multiplatform-apply-font-by-moko-resources&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@mraz3068/Compose-multiplatform-apply-font-by-moko-resources&lt;/a&gt;&lt;br /&gt;[9]&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=M1JWWHc50Kw&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=M1JWWHc50Kw&lt;/a&gt;&lt;br /&gt;[10]&amp;nbsp;&lt;a href=&quot;https://hik-coding.tistory.com/175&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hik-coding.tistory.com/175&lt;/a&gt;&lt;br /&gt;[11]&amp;nbsp;&lt;a href=&quot;https://youtrack.jetbrains.com/issue/KT-51726/Kotlin-Multiplatform-konan-llvm-1110-windows-unable-to-find-library&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtrack.jetbrains.com/issue/KT-51726/Kotlin-Multiplatform-konan-llvm-1110-windows-unable-to-find-library&lt;/a&gt;&lt;br /&gt;[12]&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/questions/68782815/skeleton-for-kotlin-native-multiproject-with-dll-library-for-backend-and-fronten&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/68782815/skeleton-for-kotlin-native-multiproject-with-dll-library-for-backend-and-fronten&lt;/a&gt;&lt;br /&gt;[13]&amp;nbsp;&lt;a href=&quot;https://deview.kr/data/deview/session/attach/6_Kotlin%20Multiplatform%20Mobile%EC%9D%84%20%ED%99%9C%EC%9A%A9%ED%95%9C%20%EB%8D%B0%EB%A7%88%EC%97%90%EC%B9%B8%20%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84%EC%95%B1%20%EA%B0%9C%EB%B0%9C%20%EC%9D%B4%EC%95%BC%EA%B8%B0.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://deview.kr/data/deview/session/attach/6_Kotlin%20Multiplatform%20Mobile%EC%9D%84%20%ED%99%9C%EC%9A%A9%ED%95%9C%20%EB%8D%B0%EB%A7%88%EC%97%90%EC%B9%B8%20%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84%EC%95%B1%20%EA%B0%9C%EB%B0%9C%20%EC%9D%B4%EC%95%BC%EA%B8%B0.pdf&lt;/a&gt;&lt;br /&gt;[14]&amp;nbsp;&lt;a href=&quot;https://proandroiddev.com/kotlin-native-use-kotlin-in-c-and-apple-framework-part-2-495a7952f831?gi=ae10bb42dd65&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://proandroiddev.com/kotlin-native-use-kotlin-in-c-and-apple-framework-part-2-495a7952f831?gi=ae10bb42dd65&lt;/a&gt;&lt;br /&gt;[15]&amp;nbsp;&lt;a href=&quot;https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-create-first-app.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-create-first-app.html&lt;/a&gt;&lt;br /&gt;[16]&amp;nbsp;&lt;a href=&quot;https://book.kotlincn.net/text/whatsnew1530.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://book.kotlincn.net/text/whatsnew1530.html&lt;/a&gt;&lt;br /&gt;[17]&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=XXkxkruDRmA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=XXkxkruDRmA&lt;/a&gt;&lt;br /&gt;[18]&amp;nbsp;&lt;a href=&quot;https://www.indeed.com/career-advice/career-development/how-to-open-dll-files&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.indeed.com/career-advice/career-development/how-to-open-dll-files&lt;/a&gt;&lt;br /&gt;[19]&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/questions/66000859/how-are-dlls-usually-packaged-with-applications&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/66000859/how-are-dlls-usually-packaged-with-applications&lt;/a&gt;&lt;br /&gt;[20]&amp;nbsp;&lt;a href=&quot;https://www.fortect.com/fix-dll-errors/run-dll-file/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.fortect.com/fix-dll-errors/run-dll-file/&lt;/a&gt;&lt;br /&gt;[21]&amp;nbsp;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170&amp;amp;redirectedfrom=MSDN&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170&amp;amp;redirectedfrom=MSDN&lt;/a&gt;&lt;br /&gt;[22]&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/questions/35401050/how-to-use-a-dll&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/35401050/how-to-use-a-dll&lt;/a&gt;&lt;br /&gt;[23]&amp;nbsp;&lt;a href=&quot;https://kb.blackbaud.com/knowledgebase/articles/Article/48280&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kb.blackbaud.com/knowledgebase/articles/Article/48280&lt;/a&gt;&lt;/p&gt;</description>
      <category>My space</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/629</guid>
      <comments>https://tourspace.tistory.com/629#entry629comment</comments>
      <pubDate>Sun, 12 Jan 2025 17:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[전주] 다슬기 나라, 다슬기탕 다슬기 수제비</title>
      <link>https://tourspace.tistory.com/623</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;전주가 백반과 가맥으로 유명한건 알았지만 다니다 보니 다슬기 식당이 꽤 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흠...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다슬기도 유명했었나 싶은데, 뭐..여튼 꽤 음식점이 보이는 데다가 검색해 보니 줄서서 먹는 다슬기 집도 있더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 늦은시간에 저녁을 먹으려고 찾은터라 정말!! 아무 블로그도, 리뷰도 없는 동네 식당을 찾아 들어갔습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HBQqw/btsJv95XWNK/bZiO77gUSwoyprujPzkCnK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HBQqw/btsJv95XWNK/bZiO77gUSwoyprujPzkCnK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HBQqw/btsJv95XWNK/bZiO77gUSwoyprujPzkCnK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHBQqw%2FbtsJv95XWNK%2FbZiO77gUSwoyprujPzkCnK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주택가 근처에 있는 동네 식당입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;손님도 광관객은 없고 동네사람들만 있습니다. 어떤 아저씨가 술을 거하게 자시고 시끄럽게 떠들긴 했습니다만, 동네식당이 다 그렇죠~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tlNT4/btsJvnDzp4G/u2tKn3I5a2wKcTBvszXbK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tlNT4/btsJvnDzp4G/u2tKn3I5a2wKcTBvszXbK1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tlNT4/btsJvnDzp4G/u2tKn3I5a2wKcTBvszXbK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtlNT4%2FbtsJvnDzp4G%2Fu2tKn3I5a2wKcTBvszXbK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg7NPn/btsJvaR0zih/4CTMTQfG7trKO2dsKkvSHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg7NPn/btsJvaR0zih/4CTMTQfG7trKO2dsKkvSHK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg7NPn/btsJvaR0zih/4CTMTQfG7trKO2dsKkvSHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg7NPn%2FbtsJvaR0zih%2F4CTMTQfG7trKO2dsKkvSHK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다슬기 탕이 나왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맑은 국물에 부추가 한가득 띄워져 나왔는데...숟가락으로 바닥을 떠보니 다슬이가 한주먹은 들어 있네요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키아...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDxlFn/btsJwaX6tHX/gHeKfkK8UtjoKSONz0jH41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDxlFn/btsJwaX6tHX/gHeKfkK8UtjoKSONz0jH41/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDxlFn/btsJwaX6tHX/gHeKfkK8UtjoKSONz0jH41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDxlFn%2FbtsJwaX6tHX%2FgHeKfkK8UtjoKSONz0jH41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhJ2L5/btsJuE0pKvj/BBE0GRkRr2VFW1mAk18fCk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhJ2L5/btsJuE0pKvj/BBE0GRkRr2VFW1mAk18fCk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhJ2L5/btsJuE0pKvj/BBE0GRkRr2VFW1mAk18fCk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhJ2L5%2FbtsJuE0pKvj%2FBBE0GRkRr2VFW1mAk18fCk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다슬기 수제비도 비슷합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에 보이는거 보다 다슬기가 훨씬 많습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 손이 미끄러져서 다슬이 통을 부으셨다 싶을정도..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국물은 깔끔하고 시원 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rkVP1/btsJvXraPMO/B0qqM9ff9wwWMV1dcDAkH0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rkVP1/btsJvXraPMO/B0qqM9ff9wwWMV1dcDAkH0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rkVP1/btsJvXraPMO/B0qqM9ff9wwWMV1dcDAkH0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrkVP1%2FbtsJvXraPMO%2FB0qqM9ff9wwWMV1dcDAkH0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다슬기 무침도 하나 시켰는데, 이게 양이 어마어마 하더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 중국집에서 여러명이 짜장면 하나씩 시키고, &quot;탕수육도 하나 시킬까?&quot; 라는 생각으로 시켰는데, 주문할때 양이 많아서 다 못먹는다고, 아주머니가 걱정을 하셨습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 한사람분 식사를 덜시키고 무침을 시킨건데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 양이 많았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmStiu/btsJuSjK1o0/qdDJmW98gO50KRlA33xx2K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmStiu/btsJuSjK1o0/qdDJmW98gO50KRlA33xx2K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmStiu/btsJuSjK1o0/qdDJmW98gO50KRlA33xx2K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmStiu%2FbtsJuSjK1o0%2FqdDJmW98gO50KRlA33xx2K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에는 그냥저냥 보이지만..저거 안쪽에 전부 다슬기 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;걍 다슬기를 퍼먹는 느낌...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새콤달콤하니 맛나더군요~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvI1lq/btsJvvn66Ph/pPqLM6H6N1UESMyuLiA270/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvI1lq/btsJvvn66Ph/pPqLM6H6N1UESMyuLiA270/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvI1lq/btsJvvn66Ph/pPqLM6H6N1UESMyuLiA270/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvI1lq%2FbtsJvvn66Ph%2FpPqLM6H6N1UESMyuLiA270%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요새 블로그를 잘 안올리는데, 이 가게 때문에 다시 쓰기 시작했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핸드폰 사진첩이 아니라 이렇게 블로그에 남겨놔야, 나중에 찾기가 편하더군요. 기억으로 연상해 내기도 쉽고..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가격이나, 양이나, 맛에서 정말 괜찮은 가게였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 전주에 가게 된다면 꼭 다시 방문해야할것 같은..(제가 원래 음식점 칭찬을 이렇게 까지는 안하는데..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 푸짐하게 다슬기를 먹을수 있는곳이니 전주에 간다면 꼭 들러보시기 바랍니다.&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EC%A0%84%EB%B6%81%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%84%EC%A3%BC%EC%8B%9C%20%EC%99%84%EC%82%B0%EA%B5%AC%20%ED%8F%89%ED%99%94%EB%8F%991%EA%B0%80%20643&amp;amp;addtype=1&amp;amp;confirmid=332303618&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A529660%2C%22mapCenterY%22%3A638143%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A529661%2C%22y%22%3A638148%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8B%A4%EC%8A%AC%EA%B8%B0%EB%82%98%EB%9D%BC%22%2C%22confirmid%22%3A332303618%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=529660&amp;amp;mapY=638143&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=5211169200&amp;amp;tel=063-237-3528&amp;amp;title=%EB%8B%A4%EC%8A%AC%EA%B8%B0%EB%82%98%EB%9D%BC&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1726924018325&quot; id=&quot;maps_1726924018325&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%A0%84%EB%B6%81%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%84%EC%A3%BC%EC%8B%9C%20%EC%99%84%EC%82%B0%EA%B5%AC%20%ED%8F%89%ED%99%94%EB%8F%991%EA%B0%80%20643&amp;amp;addtype=1&amp;amp;confirmid=332303618&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A529660%2C%22mapCenterY%22%3A638143%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A529661%2C%22y%22%3A638148%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8B%A4%EC%8A%AC%EA%B8%B0%EB%82%98%EB%9D%BC%22%2C%22confirmid%22%3A332303618%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=529660&amp;amp;mapY=638143&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=5211169200&amp;amp;tel=063-237-3528&amp;amp;title=%EB%8B%A4%EC%8A%AC%EA%B8%B0%EB%82%98%EB%9D%BC&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=529660%2C638143&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A529661%2C638148&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;</description>
      <category>소소한 일상</category>
      <category>다슬기나라</category>
      <category>다슬기무침</category>
      <category>다슬기수제비</category>
      <category>다슬기전</category>
      <category>다슬기탕</category>
      <category>전주다슬기</category>
      <category>전주다슬기식당</category>
      <category>전주맛집</category>
      <category>전주여행</category>
      <category>전주음식점</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/623</guid>
      <comments>https://tourspace.tistory.com/623#entry623comment</comments>
      <pubDate>Sat, 21 Sep 2024 22:08:00 +0900</pubDate>
    </item>
    <item>
      <title>[전주] 한벽굴, 한벽당</title>
      <link>https://tourspace.tistory.com/626</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;다시 전주로 돌아와서..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전주에서 살짝 외곽으로 나오면 길가 옆으로 한벽당과 한벽굴이 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGJ0Vj/btsJuGcRYfx/35PhhMsvLRdLcDkbNzdkY0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGJ0Vj/btsJuGcRYfx/35PhhMsvLRdLcDkbNzdkY0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGJ0Vj/btsJuGcRYfx/35PhhMsvLRdLcDkbNzdkY0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGJ0Vj%2FbtsJuGcRYfx%2F35PhhMsvLRdLcDkbNzdkY0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 한벽당의 정기를 자르려고 일제시대에 뚫었던 굴이고 철길이었다고 하네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 사람도, 차도, 자전거도 다니는길이 되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I0YkT/btsJwd8jtyC/2Y6tt5yCaAoyLakZYpYhBk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I0YkT/btsJwd8jtyC/2Y6tt5yCaAoyLakZYpYhBk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I0YkT/btsJwd8jtyC/2Y6tt5yCaAoyLakZYpYhBk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI0YkT%2FbtsJwd8jtyC%2F2Y6tt5yCaAoyLakZYpYhBk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 도로로 이어지는 굴밖의 차선은 안쪽으로 들어오면 자전거를 탈수도 있고, 산책을할수 있는 도로가 나있기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한적하니, 산책하기 좋은길 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cneFNY/btsJutktHVE/Qgg4VH0ShSorbCX0SgarBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cneFNY/btsJutktHVE/Qgg4VH0ShSorbCX0SgarBK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cneFNY/btsJutktHVE/Qgg4VH0ShSorbCX0SgarBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcneFNY%2FbtsJutktHVE%2FQgg4VH0ShSorbCX0SgarBK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 보면서 호텔 델루나에 나왔던굴이가 싶기도 했는데, 그건 아니고;;; 이정도 비주얼이면 조만간 드라마나 영화에 한번 나오지 않을까 싶네요~ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfWiiY/btsJuQ0ytlm/eMlkarzFKDukg9fHCNvHK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfWiiY/btsJuQ0ytlm/eMlkarzFKDukg9fHCNvHK0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfWiiY/btsJuQ0ytlm/eMlkarzFKDukg9fHCNvHK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfWiiY%2FbtsJuQ0ytlm%2FeMlkarzFKDukg9fHCNvHK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전주 팔경중 하나라는 한벽당 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 풍경하나 기가막힌 곳에 정차를지었네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조선시대였다면 저기 올라가서 드러누워서 강바람 쐬면서 데굴데굴 굴렀을것 같은데 말이죠..ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정자에 올라가 보려면 한벽굴을 들어오기 전에 강쪽으로 내려가는 산책길로 돌아 들어가야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 날이 더워서 그냥 밖에서 보는걸로 만족;;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/phruZ/btsJwbJuzWD/c6HNE0x0qypBgILKAboHQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/phruZ/btsJwbJuzWD/c6HNE0x0qypBgILKAboHQ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/phruZ/btsJwbJuzWD/c6HNE0x0qypBgILKAboHQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FphruZ%2FbtsJwbJuzWD%2Fc6HNE0x0qypBgILKAboHQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한벽굴에는 이런 설명이 같이 붙어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같이 붙여진 흑백 사진이 정말 추억이 돗는듯 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전주가시면 한번 들러서 보시지요. 가을에 가면 단풍이들어 정말 예쁠것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EC%A0%84%EB%B6%81%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%84%EC%A3%BC%EC%8B%9C%20%EC%99%84%EC%82%B0%EA%B5%AC%20%ED%92%8D%EB%82%A8%EB%8F%99&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A536375%2C%22mapCenterY%22%3A642993%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=536375&amp;amp;mapY=642993&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=5211153000&amp;amp;tel=&amp;amp;title=&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1726923330353&quot; id=&quot;maps_1726923330353&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%A0%84%EB%B6%81%ED%8A%B9%EB%B3%84%EC%9E%90%EC%B9%98%EB%8F%84%20%EC%A0%84%EC%A3%BC%EC%8B%9C%20%EC%99%84%EC%82%B0%EA%B5%AC%20%ED%92%8D%EB%82%A8%EB%8F%99&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A536375%2C%22mapCenterY%22%3A642993%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=536375&amp;amp;mapY=642993&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=5211153000&amp;amp;tel=&amp;amp;title=&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=536375%2C642993&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 일상</category>
      <category>전주문화관</category>
      <category>전주문화재</category>
      <category>전주볼거리</category>
      <category>전주여행</category>
      <category>전주한벽굴</category>
      <category>전주한옥마을</category>
      <category>한벽굴</category>
      <category>한벽당</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/626</guid>
      <comments>https://tourspace.tistory.com/626#entry626comment</comments>
      <pubDate>Sat, 21 Sep 2024 21:56:18 +0900</pubDate>
    </item>
    <item>
      <title>[완주 대둔산] 케이블카, 구름다리, 삼선계단</title>
      <link>https://tourspace.tistory.com/624</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;운주에서 물짜장을 먹고 가는길에 들렀습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기도 한 10년도 더 지난 예전에 친구들과 왔었던 곳인데, 부모님과도 한번 와봅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FQtzJ/btsJvaR0zNr/xKD2ltscXKYbUNOucNwKc1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FQtzJ/btsJvaR0zNr/xKD2ltscXKYbUNOucNwKc1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FQtzJ/btsJvaR0zNr/xKD2ltscXKYbUNOucNwKc1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFQtzJ%2FbtsJvaR0zNr%2FxKD2ltscXKYbUNOucNwKc1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산행을 하는건 아니고, 케이블카를 타고 살수 있으니, 녹아내릴듯한 더위지만 짤막한 산행을 도전해 봅니다. ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvXb4M/btsJIove9Y0/5vZeMCE44pkXc1EYaURLaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvXb4M/btsJIove9Y0/5vZeMCE44pkXc1EYaURLaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvXb4M/btsJIove9Y0/5vZeMCE44pkXc1EYaURLaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvXb4M%2FbtsJIove9Y0%2F5vZeMCE44pkXc1EYaURLaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;2250&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이블카 내부에 에어콘이 한대 달려있긴 한데, 그것만으로는 버티가 어려운 더위 입니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜..너무 더웠습니다.ㅠ.ㅠ 이때가 7월말이었으니..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 더운때라 사람도...없을줄 알았는데, 그래도 저같이 구경 온 사람들이 있네요 ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/46T3C/btsJt2gE4cu/KGLoaVbEEK1sd1NPe91bi0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/46T3C/btsJt2gE4cu/KGLoaVbEEK1sd1NPe91bi0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/46T3C/btsJt2gE4cu/KGLoaVbEEK1sd1NPe91bi0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F46T3C%2FbtsJt2gE4cu%2FKGLoaVbEEK1sd1NPe91bi0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상에 도착하니 밖으로 보이는 산세와 풍경이 심상치 않습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccbMdN/btsJuDN2d25/jt8534o10cTdhIwcpVz6O0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccbMdN/btsJuDN2d25/jt8534o10cTdhIwcpVz6O0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccbMdN/btsJuDN2d25/jt8534o10cTdhIwcpVz6O0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccbMdN%2FbtsJuDN2d25%2Fjt8534o10cTdhIwcpVz6O0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이블카 건물 옥상 전망대 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 음료하나 사 먹고 주위를 구경해 봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간간히 불어오는 산바람이 더위를 달래 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHiZl/btsJux8j1gT/3jcGTJzM1enlxAYPnL7LrK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHiZl/btsJux8j1gT/3jcGTJzM1enlxAYPnL7LrK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHiZl/btsJux8j1gT/3jcGTJzM1enlxAYPnL7LrK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHiZl%2FbtsJux8j1gT%2F3jcGTJzM1enlxAYPnL7LrK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전망대에서 내려다본 산세입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리나라..참 굽이굽이 산도 많네요~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFlSdW/btsJvSQRKqU/KSPHlptbKrZcPKy5a79OI1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFlSdW/btsJvSQRKqU/KSPHlptbKrZcPKy5a79OI1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFlSdW/btsJvSQRKqU/KSPHlptbKrZcPKy5a79OI1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFlSdW%2FbtsJvSQRKqU%2FKSPHlptbKrZcPKy5a79OI1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대둔산이 유명한 이유는 이 구름다리 때문 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 보면 별거 아닌거 같지만..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QNzqO/btsJt6wAgaP/bcmCMJoHUDCY8hyYcGfSEK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QNzqO/btsJt6wAgaP/bcmCMJoHUDCY8hyYcGfSEK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QNzqO/btsJt6wAgaP/bcmCMJoHUDCY8hyYcGfSEK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQNzqO%2FbtsJt6wAgaP%2FbcmCMJoHUDCY8hyYcGfSEK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;건너와서 내려다 보면..키아..다리가 오들오들 떨립니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PYLth/btsJubxEinb/zQVf28DIIR2HF2ibR3kjg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PYLth/btsJubxEinb/zQVf28DIIR2HF2ibR3kjg0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PYLth/btsJubxEinb/zQVf28DIIR2HF2ibR3kjg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPYLth%2FbtsJubxEinb%2FzQVf28DIIR2HF2ibR3kjg0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어머니가 처음에는 못건던다고 하셨는데, 간신히 건너갔다 오셨습니다. ㅎㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 걸어보면 아래가 뻥 뚫려서 더 공포감이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진 찍다가 핸드폰 떨굴까봐 엄청 꼭잡고 있었네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l7Awv/btsJvRxDFfO/UN3kFvWP2FSLUH9cKc38T0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l7Awv/btsJvRxDFfO/UN3kFvWP2FSLUH9cKc38T0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l7Awv/btsJvRxDFfO/UN3kFvWP2FSLUH9cKc38T0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl7Awv%2FbtsJvRxDFfO%2FUN3kFvWP2FSLUH9cKc38T0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 한 15년전쯤에 왔어서 2세대 다리도 건너 봤습니다. 그때 현수교였는데, 역시...제 기억이 틀린게 아니라, 2021년에 다리를 교체했네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀더 탄탄해진 느낌입니다. 사실 흔들림도 좀더 적어진것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SrS3C/btsJubEq0tx/EQZgdVEhGB1DCpd8KuBIK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SrS3C/btsJubEq0tx/EQZgdVEhGB1DCpd8KuBIK1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SrS3C/btsJubEq0tx/EQZgdVEhGB1DCpd8KuBIK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSrS3C%2FbtsJubEq0tx%2FEQZgdVEhGB1DCpd8KuBIK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람 없을때 찰칵!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 기절할만큼 덥긴 했는데, 대신 날씨는 너무 깨끗하고 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사신에 잘 보시면 삼선계단도 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번..저기까지는 못가보고 그냥 내려오는데, 저긴..너무 무섭습니다. 나이가 들고 나니, 정말 다리가 후들거릴것 같습니다. 초딩정도 되면 생각없이 뛰어 올라갈것 같습니다만..ㅎㅎㅎ 나중에 애들 데리고 와봐야 겠네요&lt;/p&gt;</description>
      <category>소소한 일상</category>
      <category>구름다리</category>
      <category>대둔산</category>
      <category>대둔산케이블카</category>
      <category>삼선계단</category>
      <category>완주 전망대</category>
      <category>완주볼거리</category>
      <category>완준가볼만한곳</category>
      <category>케이블카</category>
      <category>흔들다리</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/624</guid>
      <comments>https://tourspace.tistory.com/624#entry624comment</comments>
      <pubDate>Sat, 21 Sep 2024 21:47:09 +0900</pubDate>
    </item>
    <item>
      <title>[선릉, 양재] 삼겹살 맛집 - 돈그리아</title>
      <link>https://tourspace.tistory.com/619</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;양재에서 회식할일이 생겨서 찾은 가게 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 동네 주민 한명이 입에 침이 마르도록 추천한 곳인데, 과연 맛있다고 자부할만 하네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buIGnY/btsFQR9DJfs/oqW546oIUn7R1jRp9ki41k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buIGnY/btsFQR9DJfs/oqW546oIUn7R1jRp9ki41k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buIGnY/btsFQR9DJfs/oqW546oIUn7R1jRp9ki41k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuIGnY%2FbtsFQR9DJfs%2FoqW546oIUn7R1jRp9ki41k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 고기가 엄청 두껍습니다. 그러다 보니, 고기를 자른 모양이 일정하지는 않은데, 두껍지만 직원분이 잘 익혀 주십니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0GvgH/btsFQxjjpVY/7JW97ne3Gz72DUo0sorqu0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0GvgH/btsFQxjjpVY/7JW97ne3Gz72DUo0sorqu0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0GvgH/btsFQxjjpVY/7JW97ne3Gz72DUo0sorqu0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0GvgH%2FbtsFQxjjpVY%2F7JW97ne3Gz72DUo0sorqu0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 지나고 나니 노릇노릇 고기가 다 익었네요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보시는것처럼 숯도 정말 좋은걸 쓰는듯 하고, 특히나 고기 불판이 제가 정말 좋아하는 불판입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싸~악 불맛을 입으면서 숯에 맛있게 구워지거든요.~~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rdXzX/btsFP5ucfzV/DLnbkO2ILec6PAYcsTJvMk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rdXzX/btsFP5ucfzV/DLnbkO2ILec6PAYcsTJvMk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rdXzX/btsFP5ucfzV/DLnbkO2ILec6PAYcsTJvMk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrdXzX%2FbtsFP5ucfzV%2FDLnbkO2ILec6PAYcsTJvMk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;김치찌게밥도 하나 시켜봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훌륭합니다~~짝짝짝~~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LJ5Kx/btsFQyiczYJ/iMoOsGtxzoSf6CopPh3Nz0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LJ5Kx/btsFQyiczYJ/iMoOsGtxzoSf6CopPh3Nz0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LJ5Kx/btsFQyiczYJ/iMoOsGtxzoSf6CopPh3Nz0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLJ5Kx%2FbtsFQyiczYJ%2FiMoOsGtxzoSf6CopPh3Nz0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고추송송, 애호박까지 알차게 들어가 있어 보기만 해도 시원한 국물맛이 느껴집니다.ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어제 과음을 했더니..이 사진 보고 있노라니, 한그릇 하고 싶네요...&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tRz1v/btsFQVEewMZ/4kSeVCQutCbwHqieILN24k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tRz1v/btsFQVEewMZ/4kSeVCQutCbwHqieILN24k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tRz1v/btsFQVEewMZ/4kSeVCQutCbwHqieILN24k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtRz1v%2FbtsFQVEewMZ%2F4kSeVCQutCbwHqieILN24k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 이 가게의 시그니처 메뉴인 술리또 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;죽처럼 끓여서 나오는데, 고소하니 참 맛있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pjt8n/btsFR2bB1N9/rQgzDqN4Ykv4EKqpqUtk3K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pjt8n/btsFR2bB1N9/rQgzDqN4Ykv4EKqpqUtk3K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pjt8n/btsFR2bB1N9/rQgzDqN4Ykv4EKqpqUtk3K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpjt8n%2FbtsFR2bB1N9%2FrQgzDqN4Ykv4EKqpqUtk3K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 떠서 먹고 바질을 넣어서 한번더 끓이면 이런 비주얼이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 비주얼은 별로인데, 맛은 정말 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시각과 미각이 따로 노는 느낌..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/22xFX/btsFRcTh8Pv/QD7GGSWORAkuYxv72rjCk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/22xFX/btsFRcTh8Pv/QD7GGSWORAkuYxv72rjCk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/22xFX/btsFRcTh8Pv/QD7GGSWORAkuYxv72rjCk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F22xFX%2FbtsFRcTh8Pv%2FQD7GGSWORAkuYxv72rjCk1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 가격!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가격은 비싸지도 않고 여느 고기집과 마찬가지로 무난 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 비싸지 않은 가격에 좋은 고기를 쓰다보니, 기다리는 줄도 한참 되더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 예약이 가능하니, 방문 예정이라면 미리 예약하고 가시면 좋습니다~&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EC%84%9C%EC%9A%B8%20%EA%B0%95%EB%82%A8%EA%B5%AC%20%EB%8C%80%EC%B9%98%EB%8F%99%20897-9%201%EC%B8%B5&amp;amp;addtype=1&amp;amp;confirmid=20702726&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A511195%2C%22mapCenterY%22%3A1112038%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A511195%2C%22y%22%3A1112040%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8F%88%EA%B7%B8%EB%A6%AC%EC%95%84%22%2C%22confirmid%22%3A20702726%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=511195&amp;amp;mapY=1112038&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1168063000&amp;amp;tel=010-7303-2112&amp;amp;title=%EB%8F%88%EA%B7%B8%EB%A6%AC%EC%95%84&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1726921905888&quot; id=&quot;maps_1726921905888&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%84%9C%EC%9A%B8%20%EA%B0%95%EB%82%A8%EA%B5%AC%20%EB%8C%80%EC%B9%98%EB%8F%99%20897-9%201%EC%B8%B5&amp;amp;addtype=1&amp;amp;confirmid=20702726&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A511195%2C%22mapCenterY%22%3A1112038%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A511195%2C%22y%22%3A1112040%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8F%88%EA%B7%B8%EB%A6%AC%EC%95%84%22%2C%22confirmid%22%3A20702726%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=511195&amp;amp;mapY=1112038&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1168063000&amp;amp;tel=010-7303-2112&amp;amp;title=%EB%8F%88%EA%B7%B8%EB%A6%AC%EC%95%84&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=511195%2C1112038&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A511195%2C1112040&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소소한 일상</category>
      <category>강남맛집</category>
      <category>고기맛집</category>
      <category>돈그리아</category>
      <category>삼겹살</category>
      <category>선릉고깃집</category>
      <category>선릉삼겹살</category>
      <category>양재고깃집</category>
      <category>양재돼지고기</category>
      <category>양재맛집</category>
      <category>양재삼겹살</category>
      <author>뚜덜이~</author>
      <guid isPermaLink="true">https://tourspace.tistory.com/619</guid>
      <comments>https://tourspace.tistory.com/619#entry619comment</comments>
      <pubDate>Sat, 21 Sep 2024 21:32:51 +0900</pubDate>
    </item>
  </channel>
</rss>